View Javadoc

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   * Basic descriptors of the shape of a connected component.
39   * 
40   * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
41   * 
42   */
43  public class BasicShapeDescriptor implements ConnectedComponentProcessor, FeatureVectorProvider<DoubleFV> {
44  	/**
45  	 * An enum of all the different basic shape descriptors.
46  	 */
47  	public enum BasicShapeDescriptorType {
48  		/**
49  		 * The area of the component
50  		 * 
51  		 * @see ConnectedComponent#calculateArea()
52  		 */
53  		AREA {
54  			@Override
55  			public DoubleFV getFeatureVector(BasicShapeDescriptor desc) {
56  				return new DoubleFV(new double[] { desc.area });
57  			}
58  		},
59  		/**
60  		 * The centroid of the component
61  		 * 
62  		 * @see ConnectedComponent#calculateCentroid()
63  		 */
64  		CENTROID {
65  			@Override
66  			public DoubleFV getFeatureVector(BasicShapeDescriptor desc) {
67  				return new DoubleFV(new double[] { desc.cx, desc.cy });
68  			}
69  		},
70  		/**
71  		 * The primary orientation of the component
72  		 * 
73  		 * @see ConnectedComponent#calculateDirection()
74  		 */
75  		DIRECTION {
76  			@Override
77  			public DoubleFV getFeatureVector(BasicShapeDescriptor desc) {
78  				return new DoubleFV(new double[] { desc.direction });
79  			}
80  		},
81  		/**
82  		 * The elongatedness of the component. Elongatedness is defined as the
83  		 * ratio of the height to width of the oriented bounding box of the
84  		 * component.
85  		 * 
86  		 * @see ConnectedComponent#calculateOrientatedBoundingBoxAspectRatio()
87  		 */
88  		ELONGATEDNESS {
89  			@Override
90  			public DoubleFV getFeatureVector(BasicShapeDescriptor desc) {
91  				return new DoubleFV(new double[] { desc.elongatedness });
92  			}
93  		},
94  		/**
95  		 * The compactness of the component. Compactness is defined as the ratio
96  		 * of the squared edge length of the component to its area.
97  		 */
98  		COMPACTNESS {
99  			@Override
100 			public DoubleFV getFeatureVector(BasicShapeDescriptor desc) {
101 				return new DoubleFV(new double[] { desc.compactness });
102 			}
103 		},
104 		/**
105 		 * The ratio of the area of the component to the area of its convex hull
106 		 * 
107 		 * @see ConnectedComponent#calculatePercentageConvexHullFit()
108 		 */
109 		CHFIT {
110 			@Override
111 			public DoubleFV getFeatureVector(BasicShapeDescriptor desc) {
112 				return new DoubleFV(new double[] { desc.chfit });
113 			}
114 		},
115 		/**
116 		 * The estimated number of corners of the component
117 		 * 
118 		 * @see ConnectedComponent#estimateNumberOfVertices(int, int)
119 		 */
120 		CORNERS {
121 			@Override
122 			public DoubleFV getFeatureVector(BasicShapeDescriptor desc) {
123 				return new DoubleFV(new double[] { desc.cornerEst });
124 			}
125 		};
126 
127 		/**
128 		 * Create a @link{FeatureVector} representation of the specified
129 		 * description
130 		 * 
131 		 * @param desc
132 		 *            the descriptor
133 		 * @return the feature vector representation
134 		 */
135 		public abstract DoubleFV getFeatureVector(BasicShapeDescriptor desc);
136 	}
137 
138 	/**
139 	 * The area of the component
140 	 * 
141 	 * @see ConnectedComponent#calculateArea()
142 	 */
143 	public double area;
144 
145 	/**
146 	 * The x coordinate of the component centroid
147 	 * 
148 	 * @see ConnectedComponent#calculateCentroid()
149 	 */
150 	public double cx; // centroid x
151 
152 	/**
153 	 * The y coordinate of the component centroid
154 	 * 
155 	 * @see ConnectedComponent#calculateCentroid()
156 	 */
157 	public double cy; // y
158 
159 	/**
160 	 * The primary orientation of the component
161 	 * 
162 	 * @see ConnectedComponent#calculateDirection()
163 	 */
164 	public double direction;
165 
166 	/**
167 	 * The elongatedness of the component. Elongatedness is defined as the ratio
168 	 * of the height to width of the oriented bounding box of the component.
169 	 * 
170 	 * @see ConnectedComponent#calculateOrientatedBoundingBoxAspectRatio()
171 	 */
172 	public double elongatedness;
173 
174 	/**
175 	 * The compactness of the component. Compactness is defined as the ratio of
176 	 * the squared edge length of the component to its area.
177 	 */
178 	public double compactness;
179 
180 	/**
181 	 * The ratio of the area of the component to the area of its convex hull
182 	 * 
183 	 * @see ConnectedComponent#calculatePercentageConvexHullFit()
184 	 */
185 	public double chfit;
186 
187 	/**
188 	 * The estimated number of corners of the component
189 	 * 
190 	 * @see ConnectedComponent#estimateNumberOfVertices(int, int)
191 	 */
192 	public double cornerEst;
193 
194 	@Override
195 	public void process(ConnectedComponent cc) {
196 		area = cc.calculateArea();
197 
198 		final double[] c = cc.calculateCentroid();
199 		cx = c[0];
200 		cy = c[1];
201 
202 		direction = cc.calculateDirection();
203 
204 		elongatedness = cc.calculateOrientatedBoundingBoxAspectRatio();
205 
206 		final float edge_length = cc.getOuterBoundary().size();
207 		compactness = (edge_length * edge_length) / new ConnectedComponent(cc.toPolygon()).calculateArea();
208 
209 		if (area > 4)
210 			chfit = new ConnectedComponent(cc.toPolygon()).calculatePercentageConvexHullFit(); // chfit
211 																								// won't
212 																								// work
213 																								// for
214 																								// really
215 																								// small
216 																								// regions
217 		else
218 			chfit = 1;
219 
220 		if (area > 100)
221 			cornerEst = cc.estimateNumberOfVertices(3, 10);
222 		else
223 			cornerEst = area;
224 	}
225 
226 	/**
227 	 * Get all the values of the descriptor as an array in the order area,
228 	 * centroid_x, centroid_y, direction, elongatedness, compactness
229 	 * convex_hull_fit, corner_count
230 	 * 
231 	 * @return an array of descriptor values
232 	 */
233 	public double[] getFeatureVectorArray() {
234 		return new double[] { area, cx, cy, direction, elongatedness, compactness, chfit, cornerEst };
235 	}
236 
237 	@Override
238 	public DoubleFV getFeatureVector() {
239 		return new DoubleFV(getFeatureVectorArray());
240 	}
241 }