1 /**
2 * Copyright (c) 2011, The University of Southampton and the individual contributors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * * Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * * Neither the name of the University of Southampton nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 package org.openimaj.image.connectedcomponent.proc;
31
32 import org.openimaj.feature.DoubleFV;
33 import org.openimaj.feature.FeatureVectorProvider;
34 import org.openimaj.image.pixel.ConnectedComponent;
35 import org.openimaj.image.processor.connectedcomponent.ConnectedComponentProcessor;
36
37
38 /**
39 * Affine-invariant moment descriptor for the
40 * shape of a connected component.
41 *
42 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
43 */
44 public class AffineInvariantMoments implements ConnectedComponentProcessor, FeatureVectorProvider<DoubleFV> {
45 /**
46 * The first affine-invariant moment
47 */
48 public double I1;
49
50 /**
51 * The second affine-invariant moment
52 */
53 public double I2;
54
55 /**
56 * The third affine-invariant moment
57 */
58 public double I3;
59
60 /**
61 * The forth affine-invariant moment
62 */
63 public double I4;
64
65 @Override
66 public void process(ConnectedComponent cc) {
67 double u00 = cc.calculateMoment(0, 0);
68 double u20 = cc.calculateMoment(2, 0);
69 double u02 = cc.calculateMoment(0, 2);
70 double u11 = cc.calculateMoment(1, 1);
71 double u21 = cc.calculateMoment(2, 1);
72 double u12 = cc.calculateMoment(1, 2);
73 double u30 = cc.calculateMoment(3, 0);
74 double u03 = cc.calculateMoment(0, 3);
75
76 I1 = ((u20 * u02) - (u11*u11)) / Math.pow(u00, 4);
77
78 I2 = ((u30*u30 * u03*u03) - (6 * u30 * u21 * u12 * u03) +
79 (4 * u30 * Math.pow(u12, 3)) + (4 * Math.pow(u21, 3) * u03) - (3 * u21 * u21 * u12 *u12)) /
80 Math.pow(u00, 10);
81
82 I3 = ((u20 * (u21*u03 - u12*u12)) - (u11 * (u30*u03 - u21*u12)) + (u02 * (u30*u12 - u21*u21))) / Math.pow(u00, 7);
83
84 I4 = (Math.pow(u20, 3)*u03*u03 - 6*u20*u20*u11*u12*u03 - 6*u20*u20*u02*u21*u03 + 9*u20*u20*u02*u12*u12
85 + 12*u20*u11*u11*u21*u03 + 6*u21*u11*u02*u30*u03 - 18*u20*u11*u02*u21*u12
86 - 8*Math.pow(u11, 3)*u30*u03 - 6*u20*u02*u02*u30*u12 + 9*u20*u02*u02*u21*u21
87 + 12*u11*u11*u02*u30*u12 - 6*u11*u02*u02*u30*u21 + Math.pow(u02, 3)*u30*u30) / Math.pow(u00, 11);
88 }
89
90 @Override
91 public String toString() {
92 return String.format("%2.2f, %2.2f, %2.2f, %2.2f", I1, I2, I3, I4);
93 }
94
95 /**
96 * Get all the values of the descriptor as an array.
97 * @return an array of descriptor values
98 */
99 public double[] getFeatureVectorArray() {
100 return new double[] {I1, I2, I3, I4};
101 }
102
103 @Override
104 public DoubleFV getFeatureVector() {
105 return new DoubleFV(getFeatureVectorArray());
106 }
107 }