mv_machine_learning: add async API for face detection task group
[platform/core/api/mediavision.git] / mv_machine_learning / object_detection / src / face_detection_adapter.cpp
1 /**
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "machine_learning_exception.h"
18 #include "face_detection_adapter.h"
19
20 using namespace std;
21 using namespace MediaVision::Common;
22 using namespace mediavision::machine_learning;
23 using namespace mediavision::machine_learning::exception;
24
25 namespace mediavision
26 {
27 namespace machine_learning
28 {
29 template<typename T, typename V> FaceDetectionAdapter<T, V>::FaceDetectionAdapter() : _source()
30 {
31         // In default, FD Mobilenet v1 ssd model will be used.
32         // If other model is set by user then strategy pattern will be used
33         // to create its corresponding concerte class by calling create().
34         _object_detection = make_unique<MobilenetV1Ssd>(ObjectDetectionTaskType::FD_MOBILENET_V1_SSD);
35 }
36
37 template<typename T, typename V> FaceDetectionAdapter<T, V>::~FaceDetectionAdapter()
38 {
39         _object_detection->preDestroy();
40 }
41
42 template<typename T, typename V> void FaceDetectionAdapter<T, V>::create(int type)
43 {
44         ObjectDetectionTaskType task_type = static_cast<ObjectDetectionTaskType>(type);
45
46         // If default task type is same as a given one then skip.
47         if (_object_detection->getTaskType() == task_type)
48                 return;
49
50         _object_detection.reset();
51
52         if (task_type == ObjectDetectionTaskType::FD_MOBILENET_V1_SSD)
53                 _object_detection = make_unique<MobilenetV1Ssd>(task_type);
54         // TODO.
55 }
56
57 template<typename T, typename V>
58 void FaceDetectionAdapter<T, V>::setModelInfo(const char *model_file, const char *meta_file, const char *label_file,
59                                                                                           const char *model_name)
60 {
61         string model_name_str(model_name);
62
63         if (!model_name_str.empty()) {
64                 transform(model_name_str.begin(), model_name_str.end(), model_name_str.begin(), ::toupper);
65
66                 int model_type = 0;
67
68                 if (model_name_str == string("FD_MOBILENET_V1_SSD"))
69                         model_type = static_cast<int>(ObjectDetectionTaskType::FD_MOBILENET_V1_SSD);
70                 // TODO.
71                 else
72                         throw InvalidParameter("Invalid face detection model name.");
73
74                 create(static_cast<int>(model_type));
75         }
76
77         _model_file = string(model_file);
78         _meta_file = string(meta_file);
79         _label_file = string(label_file);
80
81         if (_model_file.empty() && _meta_file.empty() && _label_file.empty())
82                 return;
83
84         _object_detection->setUserModel(_model_file, _meta_file, _label_file);
85 }
86
87 template<typename T, typename V>
88 void FaceDetectionAdapter<T, V>::setEngineInfo(const char *engine_type, const char *device_type)
89 {
90         _object_detection->setEngineInfo(string(engine_type), string(device_type));
91 }
92
93 template<typename T, typename V> void FaceDetectionAdapter<T, V>::configure()
94 {
95         _object_detection->parseMetaFile("face_detection.json");
96         _object_detection->configure();
97 }
98
99 template<typename T, typename V> void FaceDetectionAdapter<T, V>::getNumberOfEngines(unsigned int *number_of_engines)
100 {
101         _object_detection->getNumberOfEngines(number_of_engines);
102 }
103
104 template<typename T, typename V>
105 void FaceDetectionAdapter<T, V>::getEngineType(unsigned int engine_index, char **engine_type)
106 {
107         _object_detection->getEngineType(engine_index, engine_type);
108 }
109
110 template<typename T, typename V>
111 void FaceDetectionAdapter<T, V>::getNumberOfDevices(const char *engine_type, unsigned int *number_of_devices)
112 {
113         _object_detection->getNumberOfDevices(engine_type, number_of_devices);
114 }
115
116 template<typename T, typename V>
117 void FaceDetectionAdapter<T, V>::getDeviceType(const char *engine_type, unsigned int device_index, char **device_type)
118 {
119         _object_detection->getDeviceType(engine_type, device_index, device_type);
120 }
121
122 template<typename T, typename V> void FaceDetectionAdapter<T, V>::prepare()
123 {
124         _object_detection->prepare();
125 }
126
127 template<typename T, typename V> void FaceDetectionAdapter<T, V>::setInput(T &t)
128 {
129         _source = t;
130 }
131
132 template<typename T, typename V> void FaceDetectionAdapter<T, V>::perform()
133 {
134         shared_ptr<MetaInfo> metaInfo = _object_detection->getInputMetaInfo();
135         if (metaInfo->dataType == MV_INFERENCE_DATA_UINT8)
136                 _object_detection->perform<unsigned char>(_source.inference_src, metaInfo);
137         else if (metaInfo->dataType == MV_INFERENCE_DATA_FLOAT32)
138                 _object_detection->perform<float>(_source.inference_src, metaInfo);
139         else
140                 throw InvalidOperation("Invalid model data type.");
141 }
142
143 template<typename T, typename V> void FaceDetectionAdapter<T, V>::performAsync(T &t)
144 {
145         shared_ptr<MetaInfo> metaInfo = _object_detection->getInputMetaInfo();
146
147         if (metaInfo->dataType == MV_INFERENCE_DATA_UINT8) {
148                 _object_detection->performAsync<unsigned char>(t, metaInfo);
149         } else if (metaInfo->dataType == MV_INFERENCE_DATA_FLOAT32) {
150                 _object_detection->performAsync<float>(t, metaInfo);
151                 // TODO
152         } else {
153                 throw InvalidOperation("Invalid model data type.");
154         }
155 }
156
157 template<typename T, typename V> V &FaceDetectionAdapter<T, V>::getOutput()
158 {
159         return _object_detection->getOutput<V>();
160 }
161
162 template class FaceDetectionAdapter<ObjectDetectionInput, ObjectDetectionResult>;
163 }
164 }