MACE.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. using OpenCVForUnity.CoreModule;
  2. using OpenCVForUnity.UtilsModule;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Runtime.InteropServices;
  6. namespace OpenCVForUnity.FaceModule
  7. {
  8. // C++: class MACE
  9. /**
  10. * Minimum Average Correlation Energy Filter
  11. * useful for authentication with (cancellable) biometrical features.
  12. * (does not need many positives to train (10-50), and no negatives at all, also robust to noise/salting)
  13. *
  14. * see also: CITE: Savvides04
  15. *
  16. * this implementation is largely based on: https://code.google.com/archive/p/pam-face-authentication (GSOC 2009)
  17. *
  18. * use it like:
  19. * <code>
  20. *
  21. * Ptr&lt;face::MACE&gt; mace = face::MACE::create(64);
  22. *
  23. * vector&lt;Mat&gt; pos_images = ...
  24. * mace-&gt;train(pos_images);
  25. *
  26. * Mat query = ...
  27. * bool same = mace-&gt;same(query);
  28. *
  29. * </code>
  30. *
  31. * you can also use two-factor authentication, with an additional passphrase:
  32. *
  33. * <code>
  34. * String owners_passphrase = "ilikehotdogs";
  35. * Ptr&lt;face::MACE&gt; mace = face::MACE::create(64);
  36. * mace-&gt;salt(owners_passphrase);
  37. * vector&lt;Mat&gt; pos_images = ...
  38. * mace-&gt;train(pos_images);
  39. *
  40. * // now, users have to give a valid passphrase, along with the image:
  41. * Mat query = ...
  42. * cout &lt;&lt; "enter passphrase: ";
  43. * string pass;
  44. * getline(cin, pass);
  45. * mace-&gt;salt(pass);
  46. * bool same = mace-&gt;same(query);
  47. * </code>
  48. *
  49. * save/load your model:
  50. * <code>
  51. * Ptr&lt;face::MACE&gt; mace = face::MACE::create(64);
  52. * mace-&gt;train(pos_images);
  53. * mace-&gt;save("my_mace.xml");
  54. *
  55. * // later:
  56. * Ptr&lt;MACE&gt; reloaded = MACE::load("my_mace.xml");
  57. * reloaded-&gt;same(some_image);
  58. * </code>
  59. */
  60. public class MACE : Algorithm
  61. {
  62. protected override void Dispose(bool disposing)
  63. {
  64. try
  65. {
  66. if (disposing)
  67. {
  68. }
  69. if (IsEnabledDispose)
  70. {
  71. if (nativeObj != IntPtr.Zero)
  72. face_MACE_delete(nativeObj);
  73. nativeObj = IntPtr.Zero;
  74. }
  75. }
  76. finally
  77. {
  78. base.Dispose(disposing);
  79. }
  80. }
  81. protected internal MACE(IntPtr addr) : base(addr) { }
  82. // internal usage only
  83. public static new MACE __fromPtr__(IntPtr addr) { return new MACE(addr); }
  84. //
  85. // C++: void cv::face::MACE::salt(String passphrase)
  86. //
  87. /**
  88. * optionally encrypt images with random convolution
  89. * param passphrase a crc64 random seed will get generated from this
  90. */
  91. public void salt(string passphrase)
  92. {
  93. ThrowIfDisposed();
  94. face_MACE_salt_10(nativeObj, passphrase);
  95. }
  96. //
  97. // C++: void cv::face::MACE::train(vector_Mat images)
  98. //
  99. /**
  100. * train it on positive features
  101. * compute the mace filter: {code h = D(-1) * X * (X(+) * D(-1) * X)(-1) * C}
  102. * also calculate a minimal threshold for this class, the smallest self-similarity from the train images
  103. * param images a vector&lt;Mat&gt; with the train images
  104. */
  105. public void train(List<Mat> images)
  106. {
  107. ThrowIfDisposed();
  108. Mat images_mat = Converters.vector_Mat_to_Mat(images);
  109. face_MACE_train_10(nativeObj, images_mat.nativeObj);
  110. }
  111. //
  112. // C++: bool cv::face::MACE::same(Mat query)
  113. //
  114. /**
  115. * correlate query img and threshold to min class value
  116. * param query a Mat with query image
  117. * return automatically generated
  118. */
  119. public bool same(Mat query)
  120. {
  121. ThrowIfDisposed();
  122. if (query != null) query.ThrowIfDisposed();
  123. return face_MACE_same_10(nativeObj, query.nativeObj);
  124. }
  125. //
  126. // C++: static Ptr_MACE cv::face::MACE::load(String filename, String objname = String())
  127. //
  128. /**
  129. * constructor
  130. * param filename build a new MACE instance from a pre-serialized FileStorage
  131. * param objname (optional) top-level node in the FileStorage
  132. * return automatically generated
  133. */
  134. public static MACE load(string filename, string objname)
  135. {
  136. return MACE.__fromPtr__(DisposableObject.ThrowIfNullIntPtr(face_MACE_load_10(filename, objname)));
  137. }
  138. /**
  139. * constructor
  140. * param filename build a new MACE instance from a pre-serialized FileStorage
  141. * return automatically generated
  142. */
  143. public static MACE load(string filename)
  144. {
  145. return MACE.__fromPtr__(DisposableObject.ThrowIfNullIntPtr(face_MACE_load_11(filename)));
  146. }
  147. //
  148. // C++: static Ptr_MACE cv::face::MACE::create(int IMGSIZE = 64)
  149. //
  150. /**
  151. * constructor
  152. * param IMGSIZE images will get resized to this (should be an even number)
  153. * return automatically generated
  154. */
  155. public static MACE create(int IMGSIZE)
  156. {
  157. return MACE.__fromPtr__(DisposableObject.ThrowIfNullIntPtr(face_MACE_create_10(IMGSIZE)));
  158. }
  159. /**
  160. * constructor
  161. * return automatically generated
  162. */
  163. public static MACE create()
  164. {
  165. return MACE.__fromPtr__(DisposableObject.ThrowIfNullIntPtr(face_MACE_create_11()));
  166. }
  167. #if (UNITY_IOS || UNITY_WEBGL) && !UNITY_EDITOR
  168. const string LIBNAME = "__Internal";
  169. #else
  170. const string LIBNAME = "opencvforunity";
  171. #endif
  172. // C++: void cv::face::MACE::salt(String passphrase)
  173. [DllImport(LIBNAME)]
  174. private static extern void face_MACE_salt_10(IntPtr nativeObj, string passphrase);
  175. // C++: void cv::face::MACE::train(vector_Mat images)
  176. [DllImport(LIBNAME)]
  177. private static extern void face_MACE_train_10(IntPtr nativeObj, IntPtr images_mat_nativeObj);
  178. // C++: bool cv::face::MACE::same(Mat query)
  179. [DllImport(LIBNAME)]
  180. [return: MarshalAs(UnmanagedType.U1)]
  181. private static extern bool face_MACE_same_10(IntPtr nativeObj, IntPtr query_nativeObj);
  182. // C++: static Ptr_MACE cv::face::MACE::load(String filename, String objname = String())
  183. [DllImport(LIBNAME)]
  184. private static extern IntPtr face_MACE_load_10(string filename, string objname);
  185. [DllImport(LIBNAME)]
  186. private static extern IntPtr face_MACE_load_11(string filename);
  187. // C++: static Ptr_MACE cv::face::MACE::create(int IMGSIZE = 64)
  188. [DllImport(LIBNAME)]
  189. private static extern IntPtr face_MACE_create_10(int IMGSIZE);
  190. [DllImport(LIBNAME)]
  191. private static extern IntPtr face_MACE_create_11();
  192. // native support for java finalize()
  193. [DllImport(LIBNAME)]
  194. private static extern void face_MACE_delete(IntPtr nativeObj);
  195. }
  196. }