/*
* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.IO;
using System.Runtime.InteropServices;
using InteropModel = Interop.MediaVision.FaceRecognitionModel;
namespace Tizen.Multimedia.Vision
{
///
/// Represents the face recognition model interface.
///
/// 3
public class FaceRecognitionModel : IDisposable
{
private IntPtr _handle = IntPtr.Zero;
private bool _disposed = false;
///
/// Initializes a new instance of the class.
///
/// The feature is not supported.
/// 3
public FaceRecognitionModel()
{
InteropModel.Create(out _handle).Validate("Failed to create FaceRecognitionModel");
}
///
/// Initializes a new instance of the class with the specified path.
///
///
/// Models saved by can be loaded.
///
/// Path to the model to load.
/// is null.
/// is invalid.
///
/// The feature is not supported.\n
/// -or-\n
/// is not supported format.
///
/// No permission to access the specified file.
///
/// 3
public FaceRecognitionModel(string modelPath)
{
if (modelPath == null)
{
throw new ArgumentNullException(nameof(modelPath));
}
InteropModel.Load(modelPath, out _handle).
Validate("Failed to load FaceRecognitionModel from file");
}
~FaceRecognitionModel()
{
Dispose(false);
}
///
/// Gets labels that had been learned by the model.
///
/// 3
public int[] Labels
{
get
{
IntPtr unmangedArray = IntPtr.Zero;
try
{
uint numOfLabels = 0;
InteropModel.QueryLabels(Handle, out unmangedArray, out numOfLabels).
Validate("Failed to retrieve face labels.");
int[] labels = new int[numOfLabels];
Marshal.Copy(unmangedArray, labels, 0, (int)numOfLabels);
return labels;
}
finally
{
if (unmangedArray != IntPtr.Zero)
{
LibcSupport.Free(unmangedArray);
}
}
}
}
///
/// Saves the recognition model to the file.
///
/// Path to the file to save the model.
/// is null.
/// No permission to write to the specified path.
/// The has already been disposed of.
/// The directory for does not exist.
/// 3
public void Save(string path)
{
if (path == null)
{
throw new ArgumentNullException(nameof(path));
}
var ret = InteropModel.Save(path, Handle);
if (ret == MediaVisionError.InvalidPath)
{
throw new DirectoryNotFoundException($"The directory for the path({path}) does not exist.");
}
ret.Validate("Failed to save recognition model to file");
}
private MediaVisionError InvokeAdd(MediaVisionSource source, int label, Rectangle? area)
{
if (area != null)
{
var rect = area.Value.ToMarshalable();
return InteropModel.Add(source.Handle, Handle, ref rect, label);
}
return InteropModel.Add(source.Handle, Handle, IntPtr.Zero, label);
}
///
/// Adds the face image example to be used for face recognition model learning.
///
/// The that contains face image.
/// The label that identifies face for which example is adding.
/// Specify the same labels for the face images of a single person when calling this method.
/// Has to be unique for each face.
/// is null.
///
/// The has already been disposed of.\n
/// -or-\n
/// has already been dispose of.
///
///
/// 3
public void Add(MediaVisionSource source, int label)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
InvokeAdd(source, label, null).Validate("Failed to add face example image");
}
///
/// Adds the face image example to be used for face recognition model learning.
///
/// The that contains face image.
/// The label that identifies face for which example is adding.
/// Specify the same labels for the face images of a single person when calling this method.
/// Has to be unique for each face.
/// The rectangular region of the face image at the source image.
/// is null.
///
/// The has already been disposed of.\n
/// -or-\n
/// has already been dispose of.
///
///
/// 3
public void Add(MediaVisionSource source, int label, Rectangle area)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
InvokeAdd(source, label, area).Validate("Failed to add face example image");
}
///
/// Removes all face examples added with the specified label.
///
/// The label that identifies face for which examples will be removed.
/// The has already been disposed of.
/// true if the examples are successfully removed; otherwise, false if there is no example labeled with the specified label.
///
///
/// 3
public bool Remove(int label)
{
var ret = InteropModel.Remove(Handle, ref label);
if (ret == MediaVisionError.KeyNotAvailable)
{
return false;
}
ret.Validate("Failed to remove image example");
return true;
}
///
/// Removes all face examples.
///
/// The has already been disposed of.
/// 3
public void Reset()
{
InteropModel.Reset(Handle).Validate("Failed to reset image example");
}
///
/// Learns the face recognition model.
///
///
/// Before you start the learning process, face recognition models have to be filled with the training data - face image examples.
/// These examples have to be provided by or .
/// Recognition accuracy is usually increased when the different examples of the identical faces are added more and more.
/// But it depends on the used learning algorithm.
///
/// The has already been disposed of.
/// No examples added.
///
///
/// 3
public void Learn()
{
Learn(null);
}
///
/// Learns the face recognition model with .
///
///
/// Before you start the learning process, face recognition models have to be filled with the training data - face image examples.
/// These examples have to be provided by or .
/// Recognition accuracy is usually increased when the different examples of the identical faces are added more and more.
/// But it depends on the used learning algorithm.
///
/// The configuration used for learning of the recognition models. This value can be null.
///
/// The has already been disposed of.\n
/// -or-\n
/// has already been disposed of.
///
/// No examples added.
///
///
/// 3
public void Learn(FaceRecognitionConfiguration config)
{
InteropModel.Learn(EngineConfiguration.GetHandle(config), Handle).
Validate("Failed to learn");
}
///
/// Releases all the resources used by the object.
///
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
///
/// Releases the resources used by the object.
///
///
/// true to release both managed and unmanaged resources; otherwise false to release only unmanaged resources.
///
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
InteropModel.Destroy(_handle);
_disposed = true;
}
internal IntPtr Handle
{
get
{
if (_disposed)
{
throw new ObjectDisposedException(nameof(FaceRecognitionModel));
}
return _handle;
}
}
}
}