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