mv_machine_learning: code refactoring to face recognition
authorInki Dae <inki.dae@samsung.com>
Wed, 22 Jun 2022 08:18:17 +0000 (17:18 +0900)
committerInki Dae <inki.dae@samsung.com>
Wed, 20 Jul 2022 05:16:57 +0000 (14:16 +0900)
[Issue type] code refactoring

Did code refactoring to Face recognition framework according to CAPI change.

What this refactoring does,
 - Move mv_face_recognition_result_s struct to face_recognition.cpp
   to avoid from potential ABI break.
 - Change the behavior of mv_face_recognition_inference_* functions.
   These functions return only whether error or not after inference.
 - Introduce new CAPI, mv_face_recognition_get_label_* functions.
   User can get the label string as inference result through this CAPI
   after the completion of inference.

Change-Id: Ie946a7caf9d18998597a1a21a99e252c68ee7426
Signed-off-by: Inki Dae <inki.dae@samsung.com>
include/mv_face_recognition.h
include/mv_face_recognition_type.h
mv_machine_learning/face_recognition/include/face_recognition.h
mv_machine_learning/face_recognition/include/mv_face_recognition_open.h
mv_machine_learning/face_recognition/src/face_recognition.cpp
mv_machine_learning/face_recognition/src/mv_face_recognition.c
mv_machine_learning/face_recognition/src/mv_face_recognition_open.cpp
test/testsuites/machine_learning/face_recognition/measure_face_recognition.cpp
test/testsuites/machine_learning/face_recognition/test_face_recognition.cpp

index 1b0d9cc488bd15c85764133ebac20ed013c6b644..370329fec5bc4fee893220d5084146db8a0fdd89 100644 (file)
@@ -137,7 +137,6 @@ int mv_face_recognition_unregister(mv_face_recognition_h handle, const char *lab
  *
  * @param[in] handle         The handle to the face recognition object.
  * @param[in] source         The handle to the source of the media.
- * @param[out] out_result    The structure which is filled with inference result,
  *
  * @return @c 0 on success, otherwise a negative error value
  * @retval #MEDIA_VISION_ERROR_NONE Successful
@@ -153,8 +152,27 @@ int mv_face_recognition_unregister(mv_face_recognition_h handle, const char *lab
  * @pre Prepare an face recognition by calling @ref mv_face_recognition_prepare()
  * @pre Register a new face by calling @ref mv_face_recognition_register()
  */
-int mv_face_recognition_inference(mv_face_recognition_h handle, mv_source_h source,
-                                                                 mv_face_recognition_result_s *out_result);
+int mv_face_recognition_inference(mv_face_recognition_h handle, mv_source_h source);
+
+/**
+ * @brief Get a label name.
+ * @details Use this function to get a label name after calling mv_face_recognition_inference function.
+ *
+ * @since_tizen 7.0
+ *
+ * @param[in] handle         The handle to the face recognition object.
+ * @param[out] out_label     The array pointer for the label name to be stored.
+ *                           This API returns memory pointer containing actual label string to @a out_label.
+ *                           So do not free @a out_label. And please note that @a out_label is valid only while handle is alive.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre Request a inference by calling @ref mv_face_recognition_inference()
+ */
+int mv_face_recognition_get_label(mv_face_recognition_h handle, const char **out_label);
 
 #ifdef __cplusplus
 }
index 61c3e9253ba2b9f94ddec8d586c16cd8affbdea6..f9ab44860c957f3d6d5308f9081f3de599752b42 100644 (file)
 
 #include <mv_common.h>
 
-/**
- * @brief Define MV_FACE_RECOGNITION_MAX_LABEL_LEN to indicate maximum label string length.
- *
- * @since_tizen 7.0
- */
-#define MV_FACE_RECOGNITION_MAX_LABEL_LEN      128
-/**
- * @brief Define MV_FACE_RECOGNITION_MAX_LABEL_CNT to indicate Maximum label count.
- *
- * @since_tizen 7.0
- */
-#define MV_FACE_RECOGNITION_MAX_LABEL_CNT      100
-
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
 
-/**
- * @brief The face recognition result structure.
- * @details Contains face recognition result such as label, label index, raw data,
- *          and raw data count.
- * @since_tizen 7.0
- */
-typedef struct {
-       unsigned int label_idx; /**< label index of label file. */
-       char label[MV_FACE_RECOGNITION_MAX_LABEL_LEN]; /**< label string. */
-       unsigned int raw_data_cnt; /**< raw data count which is a number of labels in label file. */
-       float raw_data[MV_FACE_RECOGNITION_MAX_LABEL_CNT]; /**< raw data to each label. */
-} mv_face_recognition_result_s;
-
 /**
  * @brief The face recognition object handle.
  *
index 33ac570778ead1e4d08525ec83f242b232fc2e26..bb79825a9f0dfa9ebd4e80e3313414887a6001c3 100644 (file)
 #include "data_augment_flip.h"
 #include "data_augment_rotate.h"
 
+namespace Mv
+{
+namespace FaceRecognition
+{
+namespace Status
+{
+       enum {
+               NONE = 0,
+               INITIALIZED,
+               REGISTERED,
+               INFERENCED,
+               DELETED
+       };
+}
+}
+}
+
+/**
+ * @brief The face recognition result structure.
+ * @details Contains face recognition result such as label, label index, raw data,
+ *          and raw data count.
+ */
+typedef struct {
+       unsigned int label_idx; /**< label index of label file. */
+       std::vector<float> raw_data; /**< raw data to each label. */
+       std::string label; /**< label string. */
+} mv_face_recognition_result_s;
+
 typedef struct {
        mv_inference_target_device_e training_target_device_type;
        mv_inference_backend_type_e training_engine_backend_type;
@@ -49,6 +77,7 @@ class FaceRecognition {
 private:
        FaceRecognitionConfig _config;
        std::vector<std::unique_ptr<DataAugment>> _data_augments;
+       mv_face_recognition_result_s _result;
 
        // FYI. This function should be called every time a new face is registered.
        void ImportLabel();
@@ -57,12 +86,12 @@ private:
        std::unique_ptr<FeatureVectorManager> CreateFVM(const mv_inference_backend_type_e backend_type, std::string file_name);
        void UpdateDataSet(std::unique_ptr<DataSetManager>& data_set, std::vector<float>& feature_vec, const int label_idx, const int label_cnt);
        void UpdateDataSet(std::unique_ptr<DataSetManager>& data_set);
-       int GetAnswer(std::vector<float>& result_tensor, unsigned int *out_idx);
+       int GetAnswer();
        std::vector<model_layer_info>& GetBackboneInputLayerInfo();
        int GetVecFromMvSource(mv_source_h img_src, std::vector<float>& out_vec);
 
 protected:
-       bool _initialized;
+       unsigned int _status;
        std::unique_ptr<mediavision::inference::Inference> _internal;
        std::unique_ptr<mediavision::inference::Inference> _backbone;
        std::unique_ptr<FaceNetInfo> _face_net_info;
@@ -70,16 +99,15 @@ protected:
        std::unique_ptr<LabelManager> _label_manager;
 
 public:
-       // decision_threshold is used to decide correct answer. Correct answer should be bigger than -0.97.
        FaceRecognition();
        ~ FaceRecognition();
 
        int Initialize();
        void SetConfig(FaceRecognitionConfig& config);
        int RegisterNewFace(mv_source_h img_src, std::string label_name);
-       int RecognizeFace(mv_source_h img_src, std::vector<float>& out_vec, unsigned int *out_idx);
+       int RecognizeFace(mv_source_h img_src);
        int DeleteLabel(std::string label_name);
-       int GetLabelWithIndex(std::string& out_label, unsigned int label_idx);
+       int GetLabel(const char **out_label);
 };
 
 #endif
\ No newline at end of file
index 4e1fe324c0954c63ff2dd15fd6b34275b51fa822..1f17b1f08eb7c1a094998e5d0100d1297ae433e5 100644 (file)
@@ -68,7 +68,7 @@ extern "C"
         *
         * @since_tizen 7.0
         *
-        * @param [out] handle    The handle to the face recognition object to be created
+        * @param[out] handle    The handle to the face recognition object to be created
         *
         * @return @c 0 on success, otherwise a negative error value
         * @retval #MEDIA_VISION_ERROR_NONE Successful
@@ -88,7 +88,7 @@ extern "C"
         *
         * @since_tizen 7.0
         *
-        * @param [in] handle    The handle to the face recognition object to be destroyed.
+        * @param[in] handle    The handle to the face recognition object to be destroyed.
         *
         * @return @c 0 on success, otherwise a negative error value
         * @retval #MEDIA_VISION_ERROR_NONE Successful
@@ -105,7 +105,7 @@ extern "C"
         *
         * @since_tizen 7.0
         *
-        * @param [in] handle    The handle to the face recognition object to be prepared.
+        * @param[in] handle    The handle to the face recognition object to be prepared.
         *
         * @return @c 0 on success, otherwise a negative error value
         * @retval #MEDIA_VISION_ERROR_NONE Successful
@@ -125,9 +125,9 @@ extern "C"
         *
         * @since_tizen 7.0
         *
-        * @param [in] handle         The handle to the face recognition object.
-        * @param [in] source         The handle to the source of the media.
-        * @param [in] label          The label to be registered. (the maximum length of the label array is 256 words)
+        * @param[in] handle         The handle to the face recognition object.
+        * @param[in] source         The handle to the source of the media.
+        * @param[in] label          The label to be registered. (the maximum length of the label array is 256 words)
         *
         * @return @c 0 on success, otherwise a negative error value
         * @retval #MEDIA_VISION_ERROR_NONE Successful
@@ -150,8 +150,8 @@ extern "C"
         *
         * @since_tizen 7.0
         *
-        * @param [in] handle         The handle to the face recognition object.
-        * @param [in] label          The label to be registered. (the maximum length of the label array is 256 words)
+        * @param[in] handle         The handle to the face recognition object.
+        * @param[in] label          The label to be registered. (the maximum length of the label array is 256 words)
         *
         * @return @c 0 on success, otherwise a negative error value
         * @retval #MEDIA_VISION_ERROR_NONE Successful
@@ -168,13 +168,12 @@ extern "C"
        /**
         * @brief Inference with a given face on the @a source
         * @details Use this function to inference with a given source.
-        *          This function returns an proper label string to a give source.
+        *
         *
         * @since_tizen 7.0
         *
-        * @param [in] handle         The handle to the face recognition object.
-        * @param [in] source         The handle to the source of the media.
-        * @param [out] out_result    The structure which is filled with inference result,
+        * @param[in] handle         The handle to the face recognition object.
+        * @param[in] source         The handle to the source of the media.
         *
         * @return @c 0 on success, otherwise a negative error value
         * @retval #MEDIA_VISION_ERROR_NONE Successful
@@ -188,8 +187,25 @@ extern "C"
         * @pre Prepare an face recognition by calling @ref mv_face_recognition_prepare_open()
         * @pre Register a new face by calling @ref mv_face_recognition_register_open()
         */
-       int mv_face_recognition_inference_open(mv_face_recognition_h handle, mv_source_h source,
-                                                                                  mv_face_recognition_result_s *out_result);
+       int mv_face_recognition_inference_open(mv_face_recognition_h handle, mv_source_h source);
+
+       /**
+        * @brief Get a label name and store it to @a out_label.
+        * @details Use this function to get a label name after calling mv_face_recognition_inference_open function.
+        *
+        * @since_tizen 7.0
+        *
+        * @param[in] handle         The handle to the face recognition object.
+        * @param[out] out_label     The array pointer for the label name to be stored.
+        *
+        * @return @c 0 on success, otherwise a negative error value
+        * @retval #MEDIA_VISION_ERROR_NONE Successful
+        * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+        * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+        *
+        * @pre Request a inference by calling @ref mv_face_recognition_inference_open()
+        */
+       int mv_face_recognition_get_label_open(mv_face_recognition_h handle, const char **out_label);
 
 #ifdef __cplusplus
 }
index 5e6816ace87e9787b8434533a49f07517f6fd5fb..ecf0d2683ac572e2a0fb51e449a0f49c2a0e20ba 100644 (file)
 using namespace std;
 using namespace mediavision::inference;
 using namespace TrainingEngineInterface::Common;
+using namespace Mv::FaceRecognition::Status;
 using namespace Mediavision::MachineLearning::Exception;
 
 FaceRecognition::FaceRecognition() :
-               _initialized(false), _internal(), _backbone(), _face_net_info(), _training_model(), _label_manager()
+               _status(NONE), _internal(), _backbone(), _face_net_info(), _training_model(), _label_manager()
 {
        _data_augments.push_back(std::make_unique<DataAugmentDefault>());
        /* Add other data argument classes. */
@@ -117,7 +118,7 @@ void FaceRecognition::UpdateDataSet(unique_ptr<DataSetManager>& data_set, vector
 
                data_set_cnt += feature_vectors.size();
 
-               // 2) If same feature vector isn't duplcated then write the feature vector to data set file.
+               // 2) If same feature vector isn't duplicated then write the feature vector to data set file.
                if (!data_set->IsFeatureVectorDuplicated(feature_vec)) {
                        fvm_new->WriteFeatureVec(feature_vec, label_cnt, label_idx);
                        LOGD("Added a new feature vector to data set file.");
@@ -183,7 +184,7 @@ int FaceRecognition::GetVecFromMvSource(mv_source_h img_src, std::vector<float>&
        }
 
        vector<model_layer_info>& input_layer_info = GetBackboneInputLayerInfo();
-       // TODO. consider mutiple tensor info.
+       // TODO. consider multiple tensor info.
        size_t re_width = input_layer_info[0].tensor_info.shape[0];
        size_t re_height = input_layer_info[0].tensor_info.shape[1];
 
@@ -253,7 +254,7 @@ int FaceRecognition::Initialize()
                return ret;
 
 
-       _initialized = true;
+       _status = INITIALIZED;
 
        return MEDIA_VISION_ERROR_NONE;
 }
@@ -279,8 +280,8 @@ int FaceRecognition::RegisterNewFace(mv_source_h img_src, string label_name)
 {
        vector<model_layer_info>& output_layer_info = _face_net_info->GetOutputLayerInfo();
 
-       if (!_initialized) {
-               LOGE("Initialization not ready yet.");
+       if (_status < INITIALIZED) {
+               LOGE("Initialization not ready yet. (%u)", _status);
                return MEDIA_VISION_ERROR_INVALID_OPERATION;
        }
 
@@ -335,6 +336,7 @@ int FaceRecognition::RegisterNewFace(mv_source_h img_src, string label_name)
                // label_cnt can be changed every time the training is performed and all data set will be used for the training
                // again in this case. So make sure to clear previous data set before next training.
                _training_model->ClearDataSet(data_set);
+               _status = REGISTERED;
        } catch (const BaseException& e) {
                LOGE("%s", e.what());
                return e.getError();
@@ -343,37 +345,37 @@ int FaceRecognition::RegisterNewFace(mv_source_h img_src, string label_name)
        return MEDIA_VISION_ERROR_NONE;
 }
 
-int FaceRecognition::GetAnswer(vector<float>& result_tensor, unsigned int *out_idx)
+int FaceRecognition::GetAnswer()
 {
        int answer_idx;
 
        string result_str;
 
        try {
-               for (auto& r : result_tensor)
+               for (auto& r : _result.raw_data)
                        result_str += to_string(r) + " ";
 
                LOGD("raw data = %s", result_str.c_str());
 
-               answer_idx = max_element(result_tensor.begin(), result_tensor.end()) - result_tensor.begin();
+               answer_idx = max_element(_result.raw_data.begin(), _result.raw_data.end()) - _result.raw_data.begin();
 
                // Check decision threshold.
-               if (result_tensor[answer_idx] < _label_manager->GetDecisionThreshold()) {
+               if (_result.raw_data[answer_idx] < _label_manager->GetDecisionThreshold()) {
                        throw NoData("Not meet decision threshold.");
                }
 
-               float weighted = result_tensor[answer_idx] * _label_manager->GetDecisionWeight();
+               float weighted = _result.raw_data[answer_idx] * _label_manager->GetDecisionWeight();
 
                // Check decision weight threshold.
-               for (auto& r : result_tensor) {
-                       if (result_tensor[answer_idx] == r)
+               for (auto& r : _result.raw_data) {
+                       if (_result.raw_data[answer_idx] == r)
                                continue;
 
                        if (weighted < r)
                                throw NoData("Not meet decision weight threshold");
                }
 
-               *out_idx = answer_idx;
+               _result.label_idx = answer_idx;
        } catch (const BaseException& e) {
                LOGE("%s", e.what());
                return e.getError();
@@ -382,10 +384,10 @@ int FaceRecognition::GetAnswer(vector<float>& result_tensor, unsigned int *out_i
        return MEDIA_VISION_ERROR_NONE;
 }
 
-int FaceRecognition::RecognizeFace(mv_source_h img_src, vector<float>& out_vec, unsigned int *out_idx)
+int FaceRecognition::RecognizeFace(mv_source_h img_src)
 {
-       if (!_initialized) {
-               LOGE("Initialization not ready yet.");
+       if (_status < INITIALIZED) {
+               LOGE("Initialization not ready yet.(%u)", _status);
                return MEDIA_VISION_ERROR_INVALID_OPERATION;
        }
 
@@ -402,7 +404,7 @@ int FaceRecognition::RecognizeFace(mv_source_h img_src, vector<float>& out_vec,
 
        // Face Recognition has following steps
        // ------------------------------------
-       // 1. Import labal data to in-memory from a file.
+       // 1. Import label data to in-memory from a file.
        // 2. Do an inference with a backbone model to get feature vector.
        // 3. Load internal model.
        // 4. Do an inference with the internal model to get a label.
@@ -477,9 +479,12 @@ int FaceRecognition::RecognizeFace(mv_source_h img_src, vector<float>& out_vec,
 
                auto raw_buffer = static_cast<float *>(internal_output_buffer->buffer);
 
-               copy(raw_buffer, raw_buffer + internal_output_buffer->size / sizeof(float), back_inserter(out_vec));
+               _result.raw_data.clear();
+               copy(raw_buffer, raw_buffer + internal_output_buffer->size / sizeof(float), back_inserter(_result.raw_data));
 
-               return GetAnswer(out_vec, out_idx);
+               _status = INFERENCED;
+
+               return GetAnswer();
        } catch (const BaseException& e) {
                LOGE("%s", e.what());
                return e.getError();
@@ -490,6 +495,11 @@ int FaceRecognition::RecognizeFace(mv_source_h img_src, vector<float>& out_vec,
 
 int FaceRecognition::DeleteLabel(string label_name)
 {
+       if (_status < INITIALIZED) {
+               LOGE("Initialization not ready yet.(%u)", _status);
+               return MEDIA_VISION_ERROR_INVALID_OPERATION;
+       }
+
        // Deleting a given label is to remove existing registered person from label and feature vector files.
 
        try {
@@ -564,6 +574,8 @@ int FaceRecognition::DeleteLabel(string label_name)
                _training_model->ApplyDataSet(new_data_set);
                _training_model->Compile();
                _training_model->Train();
+
+               _status = DELETED;
        } catch (const BaseException& e) {
                LOGE("%s", e.what());
                return e.getError();
@@ -572,14 +584,21 @@ int FaceRecognition::DeleteLabel(string label_name)
        return MEDIA_VISION_ERROR_NONE;
 }
 
-int FaceRecognition::GetLabelWithIndex(string& out_label, unsigned int label_idx)
+int FaceRecognition::GetLabel(const char **out_label)
 {
+       if (_status != INFERENCED) {
+               LOGE("Inference not completed yet.");
+               return MEDIA_VISION_ERROR_INVALID_OPERATION;
+       }
+
        try {
-               _label_manager->GetLabelString(out_label, label_idx);
+               _label_manager->GetLabelString(_result.label, _result.label_idx);
        } catch (const BaseException& e) {
                LOGE("%s", e.what());
                return e.getError();
        }
 
+       *out_label = _result.label.c_str();
+
        return MEDIA_VISION_ERROR_NONE;
-}
+}
\ No newline at end of file
index 9f833048ef6a83b383482a8ef11248758fab50b1..75513792c4409ac46dbc49209e0540a027eec83f 100644 (file)
@@ -111,21 +111,38 @@ int mv_face_recognition_unregister(mv_face_recognition_h handle, const char *lab
        return ret;
 }
 
-int mv_face_recognition_inference(mv_face_recognition_h handle, mv_source_h source,
-                                                                 mv_face_recognition_result_s *out_result)
+int mv_face_recognition_inference(mv_face_recognition_h handle, mv_source_h source)
 {
        MEDIA_VISION_SUPPORT_CHECK(
                __mv_inference_face_check_system_info_feature_supported());
 
        MEDIA_VISION_INSTANCE_CHECK(handle);
        MEDIA_VISION_INSTANCE_CHECK(source);
-       MEDIA_VISION_INSTANCE_CHECK(out_result);
 
        MEDIA_VISION_FUNCTION_ENTER();
 
        int ret = MEDIA_VISION_ERROR_NONE;
 
-       ret = mv_face_recognition_inference_open(handle, source, out_result);
+       ret = mv_face_recognition_inference_open(handle, source);
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return ret;
+}
+
+int mv_face_recognition_get_label(mv_face_recognition_h handle, const char **out_label)
+{
+       MEDIA_VISION_SUPPORT_CHECK(
+               __mv_inference_face_check_system_info_feature_supported());
+
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_INSTANCE_CHECK(out_label);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       int ret = MEDIA_VISION_ERROR_NONE;
+
+       ret = mv_face_recognition_get_label_open(handle, out_label);
 
        MEDIA_VISION_FUNCTION_LEAVE();
 
index b4b49daeb6711cf32d64676aad3d2c028f7c312a..ef5b8c1acbdca35c25b9202e5a660ebb40bf4072 100644 (file)
@@ -181,8 +181,7 @@ int mv_face_recognition_unregister_open(mv_face_recognition_h handle, const char
        return ret;
 }
 
-int mv_face_recognition_inference_open(mv_face_recognition_h handle, mv_source_h source,
-                                                                          mv_face_recognition_result_s *out_result)
+int mv_face_recognition_inference_open(mv_face_recognition_h handle, mv_source_h source)
 {
        LOGD("ENTER");
 
@@ -192,40 +191,38 @@ int mv_face_recognition_inference_open(mv_face_recognition_h handle, mv_source_h
        }
 
        FaceRecognition *pFace = static_cast<FaceRecognition *>(handle);
-       unsigned int out_idx;
-       vector<float> out_vec;
 
-       int ret = pFace->RecognizeFace(source, out_vec, &out_idx);
+       int ret = pFace->RecognizeFace(source);
        if (ret == MEDIA_VISION_ERROR_NO_DATA) {
                LOGW("Label not found.");
                return ret;
        }
 
-       out_result->label_idx = out_idx;
-       out_result->raw_data_cnt = min(static_cast<size_t>(MV_FACE_RECOGNITION_MAX_LABEL_CNT), out_vec.size());
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               LOGE("Fail to recognize face.");
 
-       copy_n(out_vec.begin(), out_result->raw_data_cnt, out_result->raw_data);
+       LOGD("LEAVE");
 
-       if (ret != MEDIA_VISION_ERROR_NONE) {
-               LOGE("Fail to recognize face.");
-               return ret;
+       return ret;
+}
+
+int mv_face_recognition_get_label_open(mv_face_recognition_h handle, const char **out_label)
+{
+       LOGD("ENTER");
+
+       if (!handle) {
+               LOGE("Handle is NULL.");
+               return MEDIA_VISION_ERROR_INVALID_PARAMETER;
        }
 
-       string result_label;
+       FaceRecognition *pFace = static_cast<FaceRecognition *>(handle);
 
-       ret = pFace->GetLabelWithIndex(result_label, out_idx);
+       int ret = pFace->GetLabel(out_label);
        if (ret != MEDIA_VISION_ERROR_NONE) {
-               LOGI("Fail to find label.");
+               LOGE("Fail to get label.");
                return ret;
        }
 
-       if (result_label.length() >= MV_FACE_RECOGNITION_MAX_LABEL_LEN - 1)
-               LOGW("Invalid label size. %d bytes will be filled only.", MV_FACE_RECOGNITION_MAX_LABEL_LEN - 1);
-
-       int length = result_label.copy(out_result->label,
-                                                                  min(result_label.length(), static_cast<size_t>(MV_FACE_RECOGNITION_MAX_LABEL_LEN)));
-       out_result->label[length] = '\0';
-
        LOGD("LEAVE");
 
        return MEDIA_VISION_ERROR_NONE;
index f6cbce28987f5a05603bf99b8ee044fdc8f634ba..82e1f856ae5214d3015c9d80aa8c446ee498c2fa 100644 (file)
@@ -127,20 +127,24 @@ TEST(FaceRecognitionAccuracy, Measure)
                ret = ImageHelper::loadImageToSource(image_path.c_str(), mv_source);
                ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
 
-               mv_face_recognition_result_s result;
+               ret = mv_face_recognition_inference(handle, mv_source);
 
-               ret =  mv_face_recognition_inference(handle, mv_source, &result);
+               bool is_no_data = (ret == MEDIA_VISION_ERROR_NO_DATA);
+               const char *out_label = NULL;
+
+               ret  = mv_face_recognition_get_label(handle, &out_label);
+               ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
 
                auto it = find(cached_label.begin(), cached_label.end(), label);
                if (it != cached_label.end()) {
                        total_positive_cnt++;
 
-                       if (label == string(result.label))
+                       if (label == string(out_label))
                                true_positive_cnt++;
                } else {
                        total_negative_cnt++;
 
-                       if (ret == MEDIA_VISION_ERROR_NO_DATA)
+                       if (is_no_data)
                                true_negative_cnt++;
                }
 
index 09bc9ef9e4a1ac78a011a9b833997760b66c4e09..50cfc3cfd0d4ba59bcff52985d0008f321e319a1 100644 (file)
@@ -109,16 +109,21 @@ TEST(FaceRecognitionTest, FaceRecognitionClassShouldBeOk)
                ret = ImageHelper::loadImageToSource(image_path.c_str(), mv_source);
                ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
 
-               mv_face_recognition_result_s result;
-
-               ret = mv_face_recognition_inference(handle, mv_source, &result);
+               ret = mv_face_recognition_inference(handle, mv_source);
                if (ret != MEDIA_VISION_ERROR_NO_DATA)
                        ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
 
                ret = mv_destroy_source(mv_source);
                ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
 
-               if (answers[image_idx++] == result.label)
+               const char *out_label = NULL;
+
+               ret  = mv_face_recognition_get_label(handle, &out_label);
+               ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+               string label_str(out_label);
+
+               if (answers[image_idx++] == label_str)
                        correct_cnt++;
        }
 
@@ -190,11 +195,12 @@ TEST(FaceRecognitionTest, FaceRecognitionClassWithEachLabelRemovalShouldBeOk)
                        ret = ImageHelper::loadImageToSource(image_path.c_str(), mv_source);
                        ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
 
-                       mv_face_recognition_result_s result;
+                       bool is_no_data = false;
+                       const char *none_str = "none";
 
-                       ret = mv_face_recognition_inference(handle, mv_source, &result);
+                       ret = mv_face_recognition_inference(handle, mv_source);
                        if (ret == MEDIA_VISION_ERROR_NO_DATA) {
-                               strcpy(result.label, "none");
+                               is_no_data = true;
                                ret = MEDIA_VISION_ERROR_NONE;
                        }
 
@@ -203,7 +209,17 @@ TEST(FaceRecognitionTest, FaceRecognitionClassWithEachLabelRemovalShouldBeOk)
                        ret = mv_destroy_source(mv_source);
                        ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
 
-                       if (answer[image_idx++] == result.label)
+                       const char *out_label = NULL;
+
+                       ret = mv_face_recognition_get_label(handle, &out_label);
+                       ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+                       if (is_no_data)
+                               out_label = const_cast<char *>(none_str);
+
+                       string label_str(out_label);
+
+                       if (answer[image_idx++] == label_str)
                                correct_cnt++;
                }