mv_machine_learning: update face recognition framework 82/279082/3 accepted/tizen/unified/20220804.151651 submit/tizen/20220803.092938
authorInki Dae <inki.dae@samsung.com>
Mon, 1 Aug 2022 09:30:04 +0000 (18:30 +0900)
committerInki Dae <inki.dae@samsung.com>
Tue, 2 Aug 2022 07:16:34 +0000 (16:16 +0900)
[Version] : 0.23.10
[Issue type] : code updating

Updated face recognition framework and its test case including cleanup
and bug fix.

What this patch does,
 - fix a bug that last label isn't removed by making all relevant files
   to be removed when last label removal is requested.
 - change default face recognition resource directory.
 - add two test cases and code cleanup to existing test cases.

Change-Id: I8e172e03d8c0f355da1cd61b4a2567086c232813
Signed-off-by: Inki Dae <inki.dae@samsung.com>
14 files changed:
mv_machine_learning/face_recognition/include/nntrainer_fvm.h
mv_machine_learning/face_recognition/include/simple_shot.h
mv_machine_learning/face_recognition/meta/face_recognition.json
mv_machine_learning/face_recognition/src/face_recognition.cpp
mv_machine_learning/face_recognition/src/nntrainer_fvm.cpp
mv_machine_learning/face_recognition/src/simple_shot.cpp
mv_machine_learning/training/include/feature_vector_manager.h
mv_machine_learning/training/include/label_manager.h
mv_machine_learning/training/include/training_model.h
mv_machine_learning/training/src/label_manager.cpp
mv_machine_learning/training/src/training_model.cpp
packaging/capi-media-vision.spec
test/testsuites/machine_learning/face_recognition/measure_face_recognition.cpp
test/testsuites/machine_learning/face_recognition/test_face_recognition.cpp

index f157840..f2647ec 100644 (file)
@@ -31,6 +31,7 @@ public:
        void WriteHeader(size_t feature_size, size_t one_hot_table_size, unsigned int  data_set_cnt) override;
        void ReadHeader(FeaVecHeader& header) override;
        void WriteFeatureVec(std::vector<float>& feature_vec, const int max_label, const int label_index) override;
+       void Remove() override;
 };
 
 #endif
\ No newline at end of file
index d9d27a5..145ac15 100644 (file)
@@ -23,7 +23,9 @@
 class SimpleShot : public TrainingModel {
 private:
        TrainingEngineBackendInfo _engine_info;
-
+private:
+       void SaveModel(const std::string file_path);
+       void RemoveModel(const std::string file_path);
 public:
        SimpleShot(const mv_inference_backend_type_e backend_type = MV_INFERENCE_BACKEND_NNTRAINER,
                           const mv_inference_target_device_e target_type = MV_INFERENCE_TARGET_DEVICE_CPU,
@@ -33,8 +35,6 @@ public:
        // Configure layers for SimpleShot learning.
        void ConfigureModel(int num_of_class);
 
-       void SaveModel(const std::string file_path);
-
        TrainingEngineBackendInfo& GetTrainingEngineInfo() { return _engine_info; }
 };
 
index db563ac..3d0bfd2 100644 (file)
@@ -4,12 +4,12 @@
         {
             "name"  : "MV_FACE_RECOGNITION_BACKBONE_MODEL_FILE_PATH",
             "type"  : "string",
-            "value" : "/usr/share/capi-media-vision/models/FR/backbone/tflite/facenet.tflite"
+            "value" : "/home/owner/media/res/face_recognition/backbone/facenet.tflite"
         },
         {
             "name"  : "MV_FACE_RECOGNITION_DEFAULT_PATH",
             "type"  : "string",
-            "value" : "/usr/share/capi-media-vision/models/FR/training/"
+            "value" : "/home/owner/media/res/face_recognition/training/"
         },
         {
             "name"  : "MV_FACE_RECOGNITION_DECISION_THRESHOLD",
index 2671134..4731d9f 100644 (file)
@@ -572,14 +572,22 @@ int FaceRecognition::DeleteLabel(string label_name)
                remove(fvm->GetFileName().c_str());
                rename(fvm_new->GetFileName().c_str(), fvm->GetFileName().c_str());
 
-               _training_model->ConfigureModel(label_cnt);
+               if (data_set_cnt == 0) {
+                       _training_model->RemoveModel();
+                       fvm->Remove();
+                       _label_manager->Remove();
 
-               unique_ptr<DataSetManager> new_data_set;
+                       LOGD("No training data so removed all relevant files.");
+               } else {
+                       _training_model->ConfigureModel(label_cnt);
 
-               UpdateDataSet(new_data_set);
-               _training_model->ApplyDataSet(new_data_set);
-               _training_model->Compile();
-               _training_model->Train();
+                       unique_ptr<DataSetManager> new_data_set;
+
+                       UpdateDataSet(new_data_set);
+                       _training_model->ApplyDataSet(new_data_set);
+                       _training_model->Compile();
+                       _training_model->Train();
+               }
 
                _status = DELETED;
        } catch (const BaseException& e) {
index 0f20e9a..22658b3 100644 (file)
@@ -85,3 +85,9 @@ void NNTrainerFVM::WriteFeatureVec(vector<float>& feature_vec, const int max_lab
                outFile.write((char *)&oneHotTable, sizeof(float));
        }
 }
+
+void NNTrainerFVM::Remove()
+{
+       // Remove existing file forcely.
+       ::remove(_feature_vector_file.c_str());
+}
\ No newline at end of file
index 25a51ad..8d31e5a 100644 (file)
@@ -132,3 +132,14 @@ void SimpleShot::SaveModel(const string file_path)
        if (ret != TRAINING_ENGINE_ERROR_NONE)
                throw InvalidOperation("Fail to save a model.");
 }
+
+void SimpleShot::RemoveModel(const string file_path)
+{
+       int ret = TRAINING_ENGINE_ERROR_NONE;
+
+       string bin_file_path = file_path.substr(0, file_path.find('.')) + ".bin";
+
+       // Remove existing files forcely.
+       ::remove(bin_file_path.c_str());
+       ::remove(file_path.c_str());
+}
\ No newline at end of file
index e6beaf5..aeca7d9 100644 (file)
@@ -54,6 +54,7 @@ public:
        virtual void WriteHeader(size_t feature_size, size_t one_hot_table_size, unsigned int  data_set_cnt) = 0;
        virtual void ReadHeader(FeaVecHeader& header) = 0;
        virtual void WriteFeatureVec(std::vector<float>& feature_vec, const int max_label, const int label_index) = 0;
+       virtual void Remove() = 0;
 
        static constexpr unsigned int feature_vector_signature = 0xFEA09841;
 };
index 082655d..9c44f22 100644 (file)
@@ -50,6 +50,7 @@ public:
        size_t GetMaxLabel(const std::string label_file);
        size_t GetMaxLabel();
        std::string GetLabelFromAnswer(const std::vector<float>& result);
+       void Remove();
 };
 
 #endif
index 5c4746e..3667534 100644 (file)
@@ -40,12 +40,14 @@ typedef struct {
 } TrainingEngineBackendInfo;
 
 class TrainingModel {
+private:
+       virtual void SaveModel(const std::string file_path) = 0;
+       virtual void RemoveModel(const std::string file_path) = 0;
 protected:
        std::unique_ptr<TrainingEngineInterface::Common::TrainingEngineCommon> _training;
        std::unique_ptr<training_engine_model> _model;
        std::unique_ptr<training_engine_dataset> _data_set;
        std::string _internal_model_file;
-
 public:
        TrainingModel(const mv_inference_backend_type_e backend_type = MV_INFERENCE_BACKEND_NNTRAINER,
                                  const mv_inference_target_device_e target_type = MV_INFERENCE_TARGET_DEVICE_CPU,
@@ -56,10 +58,10 @@ public:
        void ClearDataSet(std::unique_ptr<DataSetManager>& data_set);
        void Compile();
        void Train();
+       void RemoveModel();
 
        virtual void ConfigureModel(int num_of_class) = 0;
        virtual TrainingEngineBackendInfo& GetTrainingEngineInfo() = 0;
-       virtual void SaveModel(const std::string file_path) = 0;
 };
 
 #endif
\ No newline at end of file
index 2f65c27..11f1881 100644 (file)
@@ -279,3 +279,9 @@ string LabelManager::GetLabelFromAnswer(const vector<float>& result)
 
        return answer_label;
 }
+
+void LabelManager::Remove()
+{
+       // Remove existing files forcely.
+       ::remove(_label_file.c_str());
+}
\ No newline at end of file
index 6737791..5229b6b 100644 (file)
@@ -118,4 +118,9 @@ void TrainingModel::Train()
 
        // Save model file.
        SaveModel(_internal_model_file);
+}
+
+void TrainingModel::RemoveModel()
+{
+       RemoveModel(_internal_model_file);
 }
\ No newline at end of file
index ef00f6f..e43f4c8 100644 (file)
@@ -1,6 +1,6 @@
 Name:        capi-media-vision
 Summary:     Media Vision library for Tizen Native API
-Version:     0.23.9
+Version:     0.23.10
 Release:     0
 Group:       Multimedia/Framework
 License:     Apache-2.0 and BSD-3-Clause
index 82e1f85..80b4e40 100644 (file)
 #include "ImageHelper.h"
 #include "mv_face_recognition.h"
 
-#define TRAIN_LIST_FILE        "/usr/share/capi-media-vision/models/FR/training/train_list.txt"
-#define TEST_LIST_FILE "/usr/share/capi-media-vision/models/FR/training/test_list.txt"
+#define TRAIN_LIST_FILE        "/home/owner/media/res/face_recognition/res/measurement/train_list.txt"
+#define TEST_LIST_FILE "/home/owner/media/res/face_recognition/res/measurement/test_list.txt"
+#define TRAINING_IMAGE_PATH    "/home/owner/media/res/face_recognition/res/measurement/train/"
+#define TEST_IMAGE_PATH        "/home/owner/media/res/face_recognition/res/measurement/test/"
 #define MAX_TRAINING_CLASS                     20
 #define SHOT_PER_CLASS                         5
 
@@ -63,7 +65,7 @@ TEST(FaceRecognitionAccuracy, Measure)
 
                train_file >> filename  >> label >> index;
 
-               const string image_path = string("/usr/share/capi-media-vision/models/FR/training/train/") + filename;
+               const string image_path = string(TRAINING_IMAGE_PATH) + filename;
 
                cout << "training " << image_path << " file" << " with " << label << " train cnt = " << train_cnt << endl;
 
@@ -115,7 +117,7 @@ TEST(FaceRecognitionAccuracy, Measure)
                if (filename.empty() || label.empty() || index.empty())
                        break;
 
-               string image_path = string("/usr/share/capi-media-vision/models/FR/training/test/") + filename;
+               string image_path = string(TEST_IMAGE_PATH) + filename;
 
                cout << "inferencing " << image_path << " file" << " with " << label << " index = " << test_cnt++ << endl;
 
index 50cfc3c..c24258e 100644 (file)
@@ -23,6 +23,9 @@
 #include "ImageHelper.h"
 #include "mv_face_recognition.h"
 
+#define TRAINING_IMAGE_PATH    "/home/owner/media/res/face_recognition/res/test/training/"
+#define TEST_IMAGE_PATH                "/home/owner/media/res/face_recognition/res/test/test/"
+
 using namespace testing;
 using namespace std;
 
@@ -64,6 +67,17 @@ static const map<string, string> test_images = {
 
 using namespace MediaVision::Common;
 
+TEST(FaceRecognitionTest, FaceRecognitionSimpleTest)
+{
+       mv_face_recognition_h handle;
+
+       int ret = mv_face_recognition_create(&handle);
+       ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+       ret = mv_face_recognition_destroy(handle);
+       ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+}
+
 TEST(FaceRecognitionTest, FaceRecognitionClassShouldBeOk)
 {
        mv_face_recognition_h handle;
@@ -80,7 +94,7 @@ TEST(FaceRecognitionTest, FaceRecognitionClassShouldBeOk)
        ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
 
        for (auto& image : training_images) {
-               const string image_path = string("/usr/share/capi-media-vision/face-recognition/images/training/") + image.first;
+               const string image_path = string(TRAINING_IMAGE_PATH) + image.first;
                mv_source_h mv_source = NULL;
 
                int ret = mv_create_source(&mv_source);
@@ -100,7 +114,7 @@ TEST(FaceRecognitionTest, FaceRecognitionClassShouldBeOk)
        unsigned int correct_cnt = 0;
 
        for (auto& image : test_images) {
-               const string image_path = string("/usr/share/capi-media-vision/face-recognition/images/test/") + image.first;
+               const string image_path = string(TEST_IMAGE_PATH) + image.first;
                mv_source_h mv_source = NULL;
 
                int ret = mv_create_source(&mv_source);
@@ -161,7 +175,7 @@ TEST(FaceRecognitionTest, FaceRecognitionClassWithEachLabelRemovalShouldBeOk)
                auto& answer = answers[label_idx++];
 
                for (auto& image : training_images) {
-                       const string image_path = string("/usr/share/capi-media-vision/face-recognition/images/training/") + image.first;
+                       const string image_path = string(TRAINING_IMAGE_PATH) + image.first;
                        mv_source_h mv_source = NULL;
                        ret = mv_create_source(&mv_source);
                        ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
@@ -176,7 +190,6 @@ TEST(FaceRecognitionTest, FaceRecognitionClassWithEachLabelRemovalShouldBeOk)
                        ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
                }
 
-
                if (!label.empty()) {
                        ret = mv_face_recognition_unregister(handle, label.c_str());
                        ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
@@ -186,7 +199,7 @@ TEST(FaceRecognitionTest, FaceRecognitionClassWithEachLabelRemovalShouldBeOk)
                unsigned int correct_cnt = 0;
 
                for (auto& image : test_images) {
-                       const string image_path = string("/usr/share/capi-media-vision/face-recognition/images/test/") + image.first;
+                       const string image_path = string(TEST_IMAGE_PATH) + image.first;
                        mv_source_h mv_source = NULL;
 
                        ret = mv_create_source(&mv_source);
@@ -230,6 +243,42 @@ TEST(FaceRecognitionTest, FaceRecognitionClassWithEachLabelRemovalShouldBeOk)
        ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
 }
 
+TEST(FaceRecognitionTest, RemoveAllLabelsShouldBeOk)
+{
+       vector<string> labels = { "3448", "2929", "7779" };
+       mv_face_recognition_h handle;
+
+       int ret = mv_face_recognition_create(&handle);
+       ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+       ret = mv_face_recognition_prepare(handle);
+       ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+       for (auto& image : training_images) {
+               const string image_path = string(TRAINING_IMAGE_PATH) + image.first;
+               mv_source_h mv_source = NULL;
+               ret = mv_create_source(&mv_source);
+               ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+               ret = ImageHelper::loadImageToSource(image_path.c_str(), mv_source);
+               ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+               ret = mv_face_recognition_register(handle, mv_source, image.second.c_str());
+               ASSERT_EQ(ret, 0);
+
+               ret = mv_destroy_source(mv_source);
+               ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+       }
+
+       for (auto& label : labels) {
+               ret = mv_face_recognition_unregister(handle, label.c_str());
+               ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+       }
+
+       ret = mv_face_recognition_destroy(handle);
+       ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+}
+
 int main(int argc, char **argv)
 {
        InitGoogleTest(&argc, argv);