Moments.mm 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. //
  2. // Moments.mm
  3. //
  4. // Created by Giles Payne on 2019/10/09.
  5. //
  6. #import "Moments.h"
  7. @implementation Moments {
  8. cv::Moments native;
  9. }
  10. -(cv::Moments&)nativeRef {
  11. return native;
  12. }
  13. - (double)m00 {
  14. return native.m00;
  15. }
  16. - (void)setM00:(double)val {
  17. native.m00 = val;
  18. }
  19. - (double)m10 {
  20. return native.m10;
  21. }
  22. - (void)setM10:(double)val {
  23. native.m10 = val;
  24. }
  25. - (double)m01 {
  26. return native.m01;
  27. }
  28. - (void)setM01:(double)val {
  29. native.m01 = val;
  30. }
  31. - (double)m20 {
  32. return native.m20;
  33. }
  34. - (void)setM20:(double)val {
  35. native.m20 = val;
  36. }
  37. - (double)m11 {
  38. return native.m11;
  39. }
  40. - (void)setM11:(double)val {
  41. native.m11 = val;
  42. }
  43. - (double)m02 {
  44. return native.m02;
  45. }
  46. - (void)setM02:(double)val {
  47. native.m02 = val;
  48. }
  49. - (double)m30 {
  50. return native.m30;
  51. }
  52. - (void)setM30:(double)val {
  53. native.m30 = val;
  54. }
  55. - (double)m21 {
  56. return native.m21;
  57. }
  58. - (void)setM21:(double)val {
  59. native.m21 = val;
  60. }
  61. - (double)m12 {
  62. return native.m12;
  63. }
  64. - (void)setM12:(double)val {
  65. native.m12 = val;
  66. }
  67. - (double)m03 {
  68. return native.m03;
  69. }
  70. - (void)setM03:(double)val {
  71. native.m03 = val;
  72. }
  73. - (double)mu20 {
  74. return native.mu20;
  75. }
  76. - (void)setMu20:(double)val {
  77. native.mu20 = val;
  78. }
  79. - (double)mu11 {
  80. return native.mu11;
  81. }
  82. - (void)setMu11:(double)val {
  83. native.mu11 = val;
  84. }
  85. - (double)mu02 {
  86. return native.mu02;
  87. }
  88. - (void)setMu02:(double)val {
  89. native.mu02 = val;
  90. }
  91. - (double)mu30 {
  92. return native.mu30;
  93. }
  94. - (void)setMu30:(double)val {
  95. native.mu30 = val;
  96. }
  97. - (double)mu21 {
  98. return native.mu21;
  99. }
  100. - (void)setMu21:(double)val {
  101. native.mu21 = val;
  102. }
  103. - (double)mu12 {
  104. return native.mu12;
  105. }
  106. - (void)setMu12:(double)val {
  107. native.mu12 = val;
  108. }
  109. - (double)mu03 {
  110. return native.mu03;
  111. }
  112. - (void)setMu03:(double)val {
  113. native.mu03 = val;
  114. }
  115. - (double)nu20 {
  116. return native.nu20;
  117. }
  118. - (void)setNu20:(double)val {
  119. native.nu20 = val;
  120. }
  121. - (double)nu11 {
  122. return native.nu11;
  123. }
  124. - (void)setNu11:(double)val {
  125. native.nu11 = val;
  126. }
  127. - (double)nu02 {
  128. return native.nu02;
  129. }
  130. - (void)setNu02:(double)val {
  131. native.nu02 = val;
  132. }
  133. - (double)nu30 {
  134. return native.nu30;
  135. }
  136. - (void)setNu30:(double)val {
  137. native.nu30 = val;
  138. }
  139. - (double)nu21 {
  140. return native.nu21;
  141. }
  142. - (void)setNu21:(double)val {
  143. native.nu21 = val;
  144. }
  145. - (double)nu12 {
  146. return native.nu12;
  147. }
  148. - (void)setNu12:(double)val {
  149. native.nu12 = val;
  150. }
  151. - (double)nu03 {
  152. return native.nu03;
  153. }
  154. - (void)setNu03:(double)val {
  155. native.nu03 = val;
  156. }
  157. -(instancetype)initWithM00:(double)m00 m10:(double)m10 m01:(double)m01 m20:(double)m20 m11:(double)m11 m02:(double)m02 m30:(double)m30 m21:(double)m21 m12:(double)m12 m03:(double)m03 {
  158. self = [super init];
  159. if (self) {
  160. self.m00 = m00;
  161. self.m10 = m10;
  162. self.m01 = m01;
  163. self.m20 = m20;
  164. self.m11 = m11;
  165. self.m02 = m02;
  166. self.m30 = m30;
  167. self.m21 = m21;
  168. self.m12 = m12;
  169. self.m03 = m03;
  170. [self completeState];
  171. }
  172. return self;
  173. }
  174. -(instancetype)init {
  175. return [self initWithM00:0 m10:0 m01:0 m20:0 m11:0 m02:0 m30:0 m21:0 m12:0 m03:0];
  176. }
  177. -(instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
  178. self = [super init];
  179. if (self) {
  180. [self set:vals];
  181. }
  182. return self;
  183. }
  184. +(instancetype)fromNative:(cv::Moments&)moments {
  185. return [[Moments alloc] initWithM00:moments.m00 m10:moments.m10 m01:moments.m01 m20:moments.m20 m11:moments.m11 m02:moments.m02 m30:moments.m30 m21:moments.m21 m12:moments.m12 m03:moments.m03];
  186. }
  187. -(void)set:(NSArray<NSNumber*>*)vals {
  188. self.m00 = (vals != nil && vals.count > 0) ? vals[0].doubleValue : 0;
  189. self.m10 = (vals != nil && vals.count > 1) ? vals[1].doubleValue : 0;
  190. self.m01 = (vals != nil && vals.count > 2) ? vals[2].doubleValue : 0;
  191. self.m20 = (vals != nil && vals.count > 3) ? vals[3].doubleValue : 0;
  192. self.m11 = (vals != nil && vals.count > 4) ? vals[4].doubleValue : 0;
  193. self.m02 = (vals != nil && vals.count > 5) ? vals[5].doubleValue : 0;
  194. self.m30 = (vals != nil && vals.count > 6) ? vals[6].doubleValue : 0;
  195. self.m21 = (vals != nil && vals.count > 7) ? vals[7].doubleValue : 0;
  196. self.m12 = (vals != nil && vals.count > 8) ? vals[8].doubleValue : 0;
  197. self.m03 = (vals != nil && vals.count > 9) ? vals[9].doubleValue : 0;
  198. [self completeState];
  199. }
  200. -(void)completeState {
  201. double cx = 0, cy = 0;
  202. double mu20, mu11, mu02;
  203. double inv_m00 = 0.0;
  204. if (abs(self.m00) > 0.00000001) {
  205. inv_m00 = 1. / self.m00;
  206. cx = self.m10 * inv_m00;
  207. cy = self.m01 * inv_m00;
  208. }
  209. // mu20 = m20 - m10*cx
  210. mu20 = self.m20 - self.m10 * cx;
  211. // mu11 = m11 - m10*cy
  212. mu11 = self.m11 - self.m10 * cy;
  213. // mu02 = m02 - m01*cy
  214. mu02 = self.m02 - self.m01 * cy;
  215. self.mu20 = mu20;
  216. self.mu11 = mu11;
  217. self.mu02 = mu02;
  218. // mu30 = m30 - cx*(3*mu20 + cx*m10)
  219. self.mu30 = self.m30 - cx * (3 * mu20 + cx * self.m10);
  220. mu11 += mu11;
  221. // mu21 = m21 - cx*(2*mu11 + cx*m01) - cy*mu20
  222. self.mu21 = self.m21 - cx * (mu11 + cx * self.m01) - cy * mu20;
  223. // mu12 = m12 - cy*(2*mu11 + cy*m10) - cx*mu02
  224. self.mu12 = self.m12 - cy * (mu11 + cy * self.m10) - cx * mu02;
  225. // mu03 = m03 - cy*(3*mu02 + cy*m01)
  226. self.mu03 = self.m03 - cy * (3 * mu02 + cy * self.m01);
  227. double inv_sqrt_m00 = sqrt(abs(inv_m00));
  228. double s2 = inv_m00*inv_m00, s3 = s2*inv_sqrt_m00;
  229. self.nu20 = self.mu20*s2;
  230. self.nu11 = self.mu11*s2;
  231. self.nu02 = self.mu02*s2;
  232. self.nu30 = self.mu30*s3;
  233. self.nu21 = self.mu21*s3;
  234. self.nu12 = self.mu12*s3;
  235. self.nu03 = self.mu03*s3;
  236. }
  237. - (NSString *)description {
  238. return [NSString stringWithFormat:@"Moments [ \nm00=%lf, \nm10=%lf, m01=%lf, \nm20=%lf, m11=%lf, m02=%lf, \nm30=%lf, m21=%lf, m12=%lf, m03=%lf, \nmu20=%lf, mu11=%lf, mu02=%lf, \nmu30=%lf, mu21=%lf, mu12=%lf, mu03=%lf, \nnu20=%lf, nu11=%lf, nu02=%lf, \nnu30=%lf, nu21=%lf, nu12=%lf, nu03=%lf, \n]", self.m00, self.m10, self.m01, self.m20, self.m11, self.m02, self.m30, self.m21, self.m12, self.m03, self.mu20, self.mu11, self.mu02, self.mu30, self.mu21, self.mu12, self.mu03, self.nu20, self.nu11, self.nu02, self.nu30, self.nu21, self.nu12, self.nu03];
  239. }
  240. @end