feee3bbc08c3bf7841b0a30a7ee712b09ac824f3
[platform/core/api/mediavision.git] / mv_machine_learning / training / src / label_manager.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
20 #include "machine_learning_exception.h"
21 #include "label_manager.h"
22
23 using namespace std;
24 using namespace mediavision::machine_learning::exception;
25
26 LabelManager::LabelManager(string label_file, double decision_threshold) : _labels_and_files(), _label_file(label_file)
27 {
28         _decision_threshold = decision_threshold;
29
30         LOGD("labal file path is %s", label_file.c_str());
31         LOGD("decision_threshold value is %lf", _decision_threshold);
32 }
33
34 LabelManager::~LabelManager()
35 {}
36
37 void LabelManager::Clear()
38 {
39         _labels_and_files.clear();
40 }
41
42 float LabelManager::GetDecisionThreshold()
43 {
44         return _decision_threshold;
45 }
46
47 float LabelManager::GetDecisionWeight()
48 {
49         return _decision_weight;
50 }
51
52 unsigned int LabelManager::GetLabelIndex(const string given_label)
53 {
54         ifstream readFile;
55
56         readFile.open(_label_file.c_str());
57
58         int label_index = -1;
59
60         if (readFile.fail())
61                 throw InvalidOperation("Fail to open " + _label_file + " file.");
62
63         string line;
64
65         while (getline(readFile, line)) {
66                 label_index++;
67
68                 if (line.compare(given_label) == 0) {
69                         readFile.close();
70
71                         return label_index;
72                 }
73         }
74
75         readFile.close();
76         throw InvalidOperation("Label index not found.");
77 }
78
79 bool LabelManager::IsExist(const string given_label)
80 {
81         ifstream readFile;
82
83         readFile.open(_label_file.c_str());
84
85         int label_index = -1;
86
87         if (readFile.fail())
88                 throw InvalidOperation("Fail to open " + _label_file + " file.");
89
90         string line;
91
92         while (getline(readFile, line)) {
93                 label_index++;
94
95                 if (line.compare(given_label) == 0) {
96                         readFile.close();
97                         return true;
98                 }
99         }
100
101         readFile.close();
102         return false;
103 }
104
105 unsigned int LabelManager::RemoveLabel(const string given_label)
106 {
107         ifstream readFile;
108
109         readFile.open(_label_file.c_str());
110
111         ofstream writeFile;
112
113         string new_label_file(_label_file);
114
115         new_label_file += ".new";
116
117         writeFile.open(new_label_file.c_str(), ios::out | ios::binary);
118
119         int label_index = 0;
120
121         if (readFile.fail() || !writeFile.is_open())
122                 throw InvalidOperation("Fail to open " + _label_file + "or " + new_label_file + " file.");
123
124         string line;
125
126         while (getline(readFile, line)) {
127                 if (line.compare(given_label) != 0) {
128                         line += "\n";
129                         writeFile.write(line.c_str(), line.size());
130                         label_index++;
131                 }
132         }
133
134         readFile.close();
135         writeFile.close();
136
137         if (label_index == 0) {
138                 // Just keep original version in case of no copy so drop the new label file.
139                 int ret = ::remove(new_label_file.c_str());
140                 if (ret)
141                         throw InvalidOperation("Fail to remove label file.");
142         } else {
143                 int ret = ::remove(_label_file.c_str());
144                 if (ret)
145                         throw InvalidOperation("Fail to remove label file.");
146
147                 ret = ::rename(new_label_file.c_str(), _label_file.c_str());
148                 if (ret)
149                         throw InvalidOperation("Fail to rename new labal file to original one.");
150         }
151
152         return label_index;
153 }
154
155 int LabelManager::GetLabelString(string &label, const int idx)
156 {
157         ifstream readFile;
158
159         readFile.open(_label_file.c_str());
160
161         int label_index = -1;
162         int ret = 0;
163
164         if (readFile.fail())
165                 throw InvalidOperation("Fail to open " + _label_file + " file.");
166
167         string line;
168
169         while (getline(readFile, line)) {
170                 label_index++;
171                 line += "\n";
172
173                 if (idx == label_index) {
174                         label = line;
175                         label.erase(remove(label.begin(), label.end(), '\n'), label.end());
176                         break;
177                 }
178         }
179
180         readFile.close();
181         return ret;
182 }
183
184 unsigned int LabelManager::AddLabelToFile(string given_label)
185 {
186         ofstream writeFile;
187
188         writeFile.open(_label_file.c_str(), ios::out | ios::app);
189
190         if (!writeFile.is_open())
191                 throw InvalidOperation("Fail to open " + _label_file + " file.");
192
193         given_label += "\n";
194         writeFile.write(given_label.c_str(), given_label.size());
195         writeFile.close();
196
197         return GetMaxLabel(_label_file);
198 }
199
200 int LabelManager::ImportLabel(void)
201 {
202         // label count is 0 if lael file doesn't exist.
203         if (!FaceRecogUtil::IsFileExist(_label_file))
204                 return 0;
205
206         ifstream readFile;
207
208         readFile.open(_label_file);
209
210         int label_cnt = 0;
211
212         if (readFile.fail())
213                 throw InvalidOperation("Fail to open " + _label_file + " file.");
214
215         string line;
216
217         while (getline(readFile, line)) {
218                 bool duplicated = AddLabelToMap(line, line);
219                 if (duplicated)
220                         continue;
221
222                 label_cnt++;
223         }
224
225         readFile.close();
226
227         return label_cnt;
228 }
229
230 bool LabelManager::AddLabelToMap(const string given_label, const string image_file)
231 {
232         // Find same one if not empty. If same one exists in the map then skip.
233         if (!_labels_and_files.empty()) {
234                 auto item = _labels_and_files.find(given_label);
235                 if (item != _labels_and_files.end())
236                         return true;
237         }
238
239         _labels_and_files.insert(pair<string, string>(given_label, image_file));
240
241         return false;
242 }
243
244 size_t LabelManager::GetMaxLabel(const string label_file)
245 {
246         // label count is 0 if lael file doesn't exist.
247         if (!FaceRecogUtil::IsFileExist(label_file))
248                 return 0;
249
250         ifstream readFile;
251
252         readFile.open(label_file.c_str());
253
254         size_t label_cnt = 0;
255
256         if (readFile.fail())
257                 throw InvalidOperation("Fail to open " + label_file + " file.");
258
259         string line;
260
261         while (getline(readFile, line))
262                 label_cnt++;
263
264         readFile.close();
265
266         return label_cnt;
267 }
268
269 size_t LabelManager::GetMaxLabel()
270 {
271         return GetMaxLabel(_label_file);
272 }
273
274 string LabelManager::GetLabelFromAnswer(const vector<float> &result)
275 {
276         if (result.empty())
277                 throw InvalidParameter("result vector is empty.");
278
279         int answer_idx = max_element(result.begin(), result.end()) - result.begin();
280         if (result[answer_idx] < _decision_threshold)
281                 throw InvalidOperation("Not recognized.");
282
283         string answer_label;
284
285         int ret = GetLabelString(answer_label, answer_idx);
286         if (ret)
287                 throw InvalidOperation("answer label not found.");
288
289         return answer_label;
290 }
291
292 void LabelManager::Remove()
293 {
294         // Remove existing files forcely.
295         int ret = ::remove(_label_file.c_str());
296         if (ret)
297                 throw InvalidOperation("Fail to remove label file.");
298 }