001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package org.openimaj.image.connectedcomponent.proc; 031 032import org.openimaj.feature.DoubleFV; 033import org.openimaj.feature.FeatureVectorProvider; 034import org.openimaj.image.pixel.ConnectedComponent; 035import org.openimaj.image.processor.connectedcomponent.ConnectedComponentProcessor; 036 037 038/** 039 * Affine-invariant moment descriptor for the 040 * shape of a connected component. 041 * 042 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk) 043 */ 044public class AffineInvariantMoments implements ConnectedComponentProcessor, FeatureVectorProvider<DoubleFV> { 045 /** 046 * The first affine-invariant moment 047 */ 048 public double I1; 049 050 /** 051 * The second affine-invariant moment 052 */ 053 public double I2; 054 055 /** 056 * The third affine-invariant moment 057 */ 058 public double I3; 059 060 /** 061 * The forth affine-invariant moment 062 */ 063 public double I4; 064 065 @Override 066 public void process(ConnectedComponent cc) { 067 double u00 = cc.calculateMoment(0, 0); 068 double u20 = cc.calculateMoment(2, 0); 069 double u02 = cc.calculateMoment(0, 2); 070 double u11 = cc.calculateMoment(1, 1); 071 double u21 = cc.calculateMoment(2, 1); 072 double u12 = cc.calculateMoment(1, 2); 073 double u30 = cc.calculateMoment(3, 0); 074 double u03 = cc.calculateMoment(0, 3); 075 076 I1 = ((u20 * u02) - (u11*u11)) / Math.pow(u00, 4); 077 078 I2 = ((u30*u30 * u03*u03) - (6 * u30 * u21 * u12 * u03) + 079 (4 * u30 * Math.pow(u12, 3)) + (4 * Math.pow(u21, 3) * u03) - (3 * u21 * u21 * u12 *u12)) / 080 Math.pow(u00, 10); 081 082 I3 = ((u20 * (u21*u03 - u12*u12)) - (u11 * (u30*u03 - u21*u12)) + (u02 * (u30*u12 - u21*u21))) / Math.pow(u00, 7); 083 084 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 085 + 12*u20*u11*u11*u21*u03 + 6*u21*u11*u02*u30*u03 - 18*u20*u11*u02*u21*u12 086 - 8*Math.pow(u11, 3)*u30*u03 - 6*u20*u02*u02*u30*u12 + 9*u20*u02*u02*u21*u21 087 + 12*u11*u11*u02*u30*u12 - 6*u11*u02*u02*u30*u21 + Math.pow(u02, 3)*u30*u30) / Math.pow(u00, 11); 088 } 089 090 @Override 091 public String toString() { 092 return String.format("%2.2f, %2.2f, %2.2f, %2.2f", I1, I2, I3, I4); 093 } 094 095 /** 096 * Get all the values of the descriptor as an array. 097 * @return an array of descriptor values 098 */ 099 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}