Release 4.0.0-preview1-00321
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia.Vision / MediaVision / FaceRecognitionModel.cs
1 /*
2  * Copyright (c) 2016 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 using System;
18 using System.IO;
19 using System.Runtime.InteropServices;
20 using InteropModel = Interop.MediaVision.FaceRecognitionModel;
21
22 namespace Tizen.Multimedia.Vision
23 {
24     /// <summary>
25     /// Represents the face recognition model interface.
26     /// </summary>
27     /// <since_tizen> 3 </since_tizen>
28     public class FaceRecognitionModel : IDisposable
29     {
30         private IntPtr _handle = IntPtr.Zero;
31         private bool _disposed = false;
32
33         /// <summary>
34         /// Initializes a new instance of the <see cref="FaceRecognitionModel"/> class.
35         /// </summary>
36         /// <exception cref="NotSupportedException">The feature is not supported.</exception>
37         /// <since_tizen> 3 </since_tizen>
38         public FaceRecognitionModel()
39         {
40             InteropModel.Create(out _handle).Validate("Failed to create FaceRecognitionModel");
41         }
42
43         /// <summary>
44         /// Initializes a new instance of the <see cref="FaceRecognitionModel"/> class with the specified path.
45         /// </summary>
46         /// <remarks>
47         /// Models saved by <see cref="Save(string)"/> can be loaded.
48         /// </remarks>
49         /// <param name="modelPath">Path to the model to load.</param>
50         /// <exception cref="ArgumentNullException"><paramref name="modelPath"/> is null.</exception>
51         /// <exception cref="FileNotFoundException"><paramref name="modelPath"/> is invalid.</exception>
52         /// <exception cref="NotSupportedException">
53         ///     The feature is not supported.<br/>
54         ///     -or-<br/>
55         ///     <paramref name="modelPath"/> is not supported format.
56         /// </exception>
57         /// <exception cref="UnauthorizedAccessException">No permission to access the specified file.</exception>
58         /// <seealso cref="Save(string)"/>
59         /// <since_tizen> 3 </since_tizen>
60         public FaceRecognitionModel(string modelPath)
61         {
62             if (modelPath == null)
63             {
64                 throw new ArgumentNullException(nameof(modelPath));
65             }
66
67             InteropModel.Load(modelPath, out _handle).
68                 Validate("Failed to load FaceRecognitionModel from file");
69         }
70
71         /// <summary>
72         /// Finalizes an instance of the FaceRecognitionModel class.
73         /// </summary>
74         ~FaceRecognitionModel()
75         {
76             Dispose(false);
77         }
78
79         /// <summary>
80         /// Gets labels that had been learned by the model.
81         /// </summary>
82         /// <since_tizen> 3</since_tizen>
83         public int[] Labels
84         {
85             get
86             {
87                 IntPtr unmangedArray = IntPtr.Zero;
88                 try
89                 {
90                     uint numOfLabels = 0;
91
92                     InteropModel.QueryLabels(Handle, out unmangedArray, out numOfLabels).
93                         Validate("Failed to retrieve face labels.");
94
95                     int[] labels = new int[numOfLabels];
96                     Marshal.Copy(unmangedArray, labels, 0, (int)numOfLabels);
97
98                     return labels;
99                 }
100                 finally
101                 {
102                     if (unmangedArray != IntPtr.Zero)
103                     {
104                         LibcSupport.Free(unmangedArray);
105                     }
106                 }
107             }
108         }
109
110         /// <summary>
111         /// Saves the recognition model to the file.
112         /// </summary>
113         /// <param name="path">Path to the file to save the model.</param>
114         /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
115         /// <exception cref="UnauthorizedAccessException">No permission to write to the specified path.</exception>
116         /// <exception cref="ObjectDisposedException">The <see cref="FaceRecognitionModel"/> has already been disposed of.</exception>
117         /// <exception cref="DirectoryNotFoundException">The directory for <paramref name="path"/> does not exist.</exception>
118         /// <since_tizen> 3 </since_tizen>
119         public void Save(string path)
120         {
121             if (path == null)
122             {
123                 throw new ArgumentNullException(nameof(path));
124             }
125
126             var ret = InteropModel.Save(path, Handle);
127
128             if (ret == MediaVisionError.InvalidPath)
129             {
130                 throw new DirectoryNotFoundException($"The directory for the path({path}) does not exist.");
131             }
132
133             ret.Validate("Failed to save recognition model to file");
134         }
135
136         private MediaVisionError InvokeAdd(MediaVisionSource source, int label, Rectangle? area)
137         {
138             if (area != null)
139             {
140                 var rect = area.Value.ToMarshalable();
141                 return InteropModel.Add(source.Handle, Handle, ref rect, label);
142             }
143
144             return InteropModel.Add(source.Handle, Handle, IntPtr.Zero, label);
145         }
146
147         /// <summary>
148         /// Adds the face image example to be used for face recognition model learning.
149         /// </summary>
150         /// <param name="source">The <see cref="MediaVisionSource"/> that contains face image.</param>
151         /// <param name="label">The label that identifies face for which example is adding.
152         ///     Specify the same labels for the face images of a single person when calling this method.
153         ///     Has to be unique for each face.</param>
154         /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
155         /// <exception cref="ObjectDisposedException">
156         ///     The <see cref="FaceRecognitionModel"/> has already been disposed of.<br/>
157         ///     -or-<br/>
158         ///     <paramref name="source"/> has already been dispose of.
159         /// </exception>
160         /// <seealso cref="Learn(FaceRecognitionConfiguration)"/>
161         /// <since_tizen> 3 </since_tizen>
162         public void Add(MediaVisionSource source, int label)
163         {
164             if (source == null)
165             {
166                 throw new ArgumentNullException(nameof(source));
167             }
168
169             InvokeAdd(source, label, null).Validate("Failed to add face example image");
170         }
171
172         /// <summary>
173         /// Adds the face image example to be used for face recognition model learning.
174         /// </summary>
175         /// <param name="source">The <see cref="MediaVisionSource"/> that contains face image.</param>
176         /// <param name="label">The label that identifies face for which example is adding.
177         ///     Specify the same labels for the face images of a single person when calling this method.
178         ///     Has to be unique for each face.</param>
179         /// <param name="area">The rectangular region of the face image at the source image.</param>
180         /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
181         /// <exception cref="ObjectDisposedException">
182         ///     The <see cref="FaceRecognitionModel"/> has already been disposed of.<br/>
183         ///     -or-<br/>
184         ///     <paramref name="source"/> has already been dispose of.
185         /// </exception>
186         /// <seealso cref="Learn(FaceRecognitionConfiguration)"/>
187         /// <since_tizen> 3 </since_tizen>
188         public void Add(MediaVisionSource source, int label, Rectangle area)
189         {
190             if (source == null)
191             {
192                 throw new ArgumentNullException(nameof(source));
193             }
194
195             InvokeAdd(source, label, area).Validate("Failed to add face example image");
196         }
197
198         /// <summary>
199         /// Removes all face examples added with the specified label.
200         /// </summary>
201         /// <param name="label">The label that identifies face for which examples will be removed.</param>
202         /// <exception cref="ObjectDisposedException">The <see cref="FaceRecognitionModel"/> has already been disposed of.</exception>
203         /// <returns>true if the examples are successfully removed; otherwise, false if there is no example labeled with the specified label.</returns>
204         /// <seealso cref="Add(MediaVisionSource, int)"/>
205         /// <seealso cref="Add(MediaVisionSource, int, Rectangle)"/>
206         /// <since_tizen> 3 </since_tizen>
207         public bool Remove(int label)
208         {
209             var ret = InteropModel.Remove(Handle, ref label);
210
211             if (ret == MediaVisionError.KeyNotAvailable)
212             {
213                 return false;
214             }
215
216             ret.Validate("Failed to remove image example");
217             return true;
218         }
219
220         /// <summary>
221         /// Removes all face examples.
222         /// </summary>
223         /// <exception cref="ObjectDisposedException">The <see cref="FaceRecognitionModel"/> has already been disposed of.</exception>
224         /// <since_tizen> 3 </since_tizen>
225         public void Reset()
226         {
227             InteropModel.Reset(Handle).Validate("Failed to reset image example");
228         }
229
230
231         /// <summary>
232         /// Learns the face recognition model.
233         /// </summary>
234         /// <remarks>
235         /// Before you start the learning process, face recognition models have to be filled with the training data - face image examples.
236         /// These examples have to be provided by <see cref="Add(MediaVisionSource, int)"/> or <see cref="Add(MediaVisionSource, int, Rectangle)"/>.
237         /// Recognition accuracy is usually increased when the different examples of the identical faces are added more and more.
238         /// But it depends on the used learning algorithm.
239         /// </remarks>
240         /// <exception cref="ObjectDisposedException">The <see cref="FaceRecognitionModel"/> has already been disposed of.</exception>
241         /// <exception cref="InvalidOperationException">No examples added.</exception>
242         /// <seealso cref="Add(MediaVisionSource, int)"/>
243         /// <seealso cref="Add(MediaVisionSource, int, Rectangle)"/>
244         /// <since_tizen> 3 </since_tizen>
245         public void Learn()
246         {
247             Learn(null);
248         }
249
250         /// <summary>
251         /// Learns the face recognition model with <see cref="FaceRecognitionConfiguration"/>.
252         /// </summary>
253         /// <remarks>
254         /// Before you start the learning process, face recognition models have to be filled with the training data - face image examples.
255         /// These examples have to be provided by <see cref="Add(MediaVisionSource, int)"/> or <see cref="Add(MediaVisionSource, int, Rectangle)"/>.
256         /// Recognition accuracy is usually increased when the different examples of the identical faces are added more and more.
257         /// But it depends on the used learning algorithm.
258         /// </remarks>
259         /// <param name="config">The configuration used for learning of the recognition models. This value can be null.</param>
260         /// <exception cref="ObjectDisposedException">
261         ///     The <see cref="FaceRecognitionModel"/> has already been disposed of.<br/>
262         ///     -or-<br/>
263         ///     <paramref name="config"/> has already been disposed of.
264         /// </exception>
265         /// <exception cref="InvalidOperationException">No examples added.</exception>
266         /// <seealso cref="Add(MediaVisionSource, int)"/>
267         /// <seealso cref="Add(MediaVisionSource, int, Rectangle)"/>
268         /// <since_tizen> 3 </since_tizen>
269         public void Learn(FaceRecognitionConfiguration config)
270         {
271             InteropModel.Learn(EngineConfiguration.GetHandle(config), Handle).
272                 Validate("Failed to learn");
273         }
274
275         /// <summary>
276         /// Releases all the resources used by the <see cref="FaceRecognitionModel"/> object.
277         /// </summary>
278         public void Dispose()
279         {
280             Dispose(true);
281             GC.SuppressFinalize(this);
282         }
283
284         /// <summary>
285         /// Releases the resources used by the <see cref="FaceRecognitionModel"/> object.
286         /// </summary>
287         /// <param name="disposing">
288         /// true to release both managed and unmanaged resources; otherwise false to release only unmanaged resources.
289         /// </param>
290         protected virtual void Dispose(bool disposing)
291         {
292             if (_disposed)
293             {
294                 return;
295             }
296
297             InteropModel.Destroy(_handle);
298             _disposed = true;
299         }
300
301         internal IntPtr Handle
302         {
303             get
304             {
305                 if (_disposed)
306                 {
307                     throw new ObjectDisposedException(nameof(FaceRecognitionModel));
308                 }
309                 return _handle;
310             }
311         }
312     }
313 }