5611daf0dcff84d98f3a18e21a3ac024162562c6
[platform/core/api/mediavision.git] / mv_machine_learning / face_recognition / src / face_recognition_dsm.cpp
1 /**
2  * Copyright (c) 2022 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 <dlog.h>
18 #include <mv_private.h>
19 #include <algorithm>
20
21 #include "machine_learning_exception.h"
22 #include "face_recognition_dsm.h"
23 #define MAX_FEATURE_VECTOR_CNT 5
24
25 using namespace std;
26 using namespace mediavision::machine_learning::exception;
27
28 void FaceRecognitionDSM::PrintHeader(FeaVecHeader &fvh)
29 {
30         LOGD("signature = %u", fvh.signature);
31         LOGD("feature vector size = %zu", fvh.feature_size);
32         LOGD("label count = %zu", fvh.label_cnt);
33         LOGD("data set count = %u", fvh.data_set_cnt);
34 }
35
36 FaceRecognitionDSM::FaceRecognitionDSM() : DataSetManager()
37 {}
38
39 bool FaceRecognitionDSM::IsFeatureVectorAllowed(unsigned int label_idx)
40 {
41         return (_fv_cnt_per_label[label_idx] < MAX_FEATURE_VECTOR_CNT);
42 }
43
44 void FaceRecognitionDSM::AddDataSet(std::vector<float> &feature_vec, const unsigned int label_idx,
45                                                                         const unsigned int label_cnt)
46 {
47         _data.push_back(feature_vec);
48         _label_index.push_back(label_idx);
49         _fv_cnt_per_label[label_idx]++;
50
51         vector<float> oneHotEncoding;
52
53         for (size_t num = 0; num < label_cnt; ++num)
54                 oneHotEncoding.push_back(label_idx == num ? 1.0f : 0.0f);
55
56         _labels.push_back(oneHotEncoding);
57         _feature_vector_size = feature_vec.size();
58         _label_count = label_cnt;
59 }
60
61 void FaceRecognitionDSM::LoadDataSet(const string file_name, unsigned int new_label_cnt)
62 {
63         std::ifstream inFile(file_name);
64
65         if (!inFile.is_open())
66                 throw InvalidOperation("fail to open a file.");
67
68         // Feature vector file header is written at the end of the data file
69         // So read feature vector header from the end of the file.
70         inFile.seekg(static_cast<int>(sizeof(FeaVecHeader)) * -1, ios::end);
71
72         FeaVecHeader fvh;
73
74         inFile.read((char *) &fvh, sizeof(FeaVecHeader));
75         if (inFile.gcount() != sizeof(FeaVecHeader))
76                 throw InvalidOperation("Invalid feature vector file.");
77
78         inFile.seekg(0, ios::beg);
79
80         PrintHeader(fvh);
81
82         if (FeatureVectorManager::feature_vector_signature != fvh.signature)
83                 throw InvalidOperation("Wrong feature vector header.");
84
85         /*
86         * stride line format is as follows
87         * ********************************
88         * ____________________________
89         * |feature vector|label index|
90         * ----------------------------
91         */
92         size_t line_size_in_bytes = fvh.feature_size * sizeof(float) + sizeof(unsigned int);
93
94         _feature_vector_size = fvh.feature_size;
95         _label_count = fvh.label_cnt;
96
97         vector<float> line_data(fvh.feature_size + 1);
98
99         for (size_t idx = 0; idx < fvh.data_set_cnt; ++idx) {
100                 inFile.read(reinterpret_cast<char *>(line_data.data()), line_size_in_bytes);
101
102                 vector<float> data;
103
104                 copy_n(line_data.begin(), _feature_vector_size, back_inserter(data));
105                 _data.push_back(data);
106
107                 unsigned int label_idx;
108
109                 memcpy(&label_idx, reinterpret_cast<void *>(line_data.data() + _feature_vector_size), sizeof(unsigned int));
110
111                 vector<float> label;
112
113                 // max label count may be changed so update one hot encoding table.
114                 for (size_t num = 0; num < new_label_cnt; ++num)
115                         label.push_back(label_idx == num ? 1.0f : 0.0f);
116
117                 _labels.push_back(label);
118                 _label_index.push_back(label_idx);
119
120                 _fv_cnt_per_label[label_idx]++;
121         }
122 }