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