using DlibDotNet; using System.Runtime.Serialization; namespace View_by_Distance.FaceRecognitionDotNet.Models; /// <summary> /// Represents a feature data of face. This class cannot be inherited. /// </summary> [Serializable] public sealed class FaceEncoding : DisposableObject, ISerializable { #region Fields [NonSerialized] private readonly Matrix<double> _Encoding; #endregion #region Constructors internal FaceEncoding(Matrix<double> encoding) => _Encoding = encoding; private FaceEncoding(SerializationInfo info, StreamingContext context) { if (info == null) throw new NullReferenceException(nameof(info)); double[]? array = info.GetValue(nameof(_Encoding), typeof(double[])) as double[]; int? row = (int?)info.GetValue(nameof(_Encoding.Rows), typeof(int)); int? column = (int?)info.GetValue(nameof(_Encoding.Columns), typeof(int)); if (row is null) throw new NullReferenceException(nameof(row)); if (column is null) throw new NullReferenceException(nameof(column)); _Encoding = new Matrix<double>(array, row.Value, column.Value); } #endregion #region Properties internal Matrix<double> Encoding => _Encoding; /// <summary> /// Gets the size of feature data. /// </summary> /// <exception cref="ObjectDisposedException">This object is disposed.</exception> public int Size { get { ThrowIfDisposed(); return _Encoding.Size; } } #endregion #region Methods /// <summary> /// Gets a feature data of face as raw format. /// </summary> /// <returns>A <see cref="double"/> array that represents a feature data.</returns> /// <remarks><see cref="FaceEncoding"/> class supports serialization. This method is for interoperability between FaceRecognitionotNet and dlib.</remarks> /// <exception cref="ObjectDisposedException">This object is disposed.</exception> public double[] GetRawEncoding() { ThrowIfDisposed(); return _Encoding.ToArray(); } #region Overrides /// <summary> /// Releases all unmanaged resources. /// </summary> protected override void DisposeUnmanaged() { base.DisposeUnmanaged(); _Encoding?.Dispose(); } #endregion #endregion #region ISerializable Members /// <summary> /// Populates a <see cref="SerializationInfo"/> with the data needed to serialize the target object. /// </summary> /// <param name="info">The <see cref="SerializationInfo"/> to populate with data.</param> /// <param name="context">The destination (see <see cref="StreamingContext"/>) for this serialization.</param> public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue(nameof(_Encoding), _Encoding.ToArray()); info.AddValue(nameof(_Encoding.Rows), _Encoding.Rows); info.AddValue(nameof(_Encoding.Columns), _Encoding.Columns); } #endregion }