/*
* This file is part of the LIRE project: http://www.semanticmetadata.net/lire
* LIRE is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* LIRE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LIRE; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* We kindly ask you to refer the any or one of the following publications in
* any publication mentioning or employing Lire:
*
* Lux Mathias, Savvas A. Chatzichristofis. Lire: Lucene Image Retrieval –
* An Extensible Java CBIR Library. In proceedings of the 16th ACM International
* Conference on Multimedia, pp. 1085-1088, Vancouver, Canada, 2008
* URL: http://doi.acm.org/10.1145/1459359.1459577
*
* Lux Mathias. Content Based Image Retrieval with LIRE. In proceedings of the
* 19th ACM International Conference on Multimedia, pp. 735-738, Scottsdale,
* Arizona, USA, 2011
* URL: http://dl.acm.org/citation.cfm?id=2072432
*
* Mathias Lux, Oge Marques. Visual Information Retrieval using Java and LIRE
* Morgan & Claypool, 2013
* URL: http://www.morganclaypool.com/doi/abs/10.2200/S00468ED1V01Y201301ICR025
*
* Copyright statement:
* --------------------
* (c) 2002-2013 by Mathias Lux (mathias@juggle.at)
* http://www.semanticmetadata.net/lire, http://www.lire-project.net
*/
package net.semanticmetadata.lire.imageanalysis.mser;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* The GrowthHistory holds the information for ONE Extremal Region!!
* <p/>
* User: Shotty
* Date: 28.06.2010
* Time: 11:04:17
*/
public class MSERGrowthHistory implements Comparable {
int index;
int size;
int maxGreyValue;
LinkedImagePoint head;
ImagePoint[] points = null;
ImagePoint[] borderPoints = null;
MSERGrowthHistory parent;
public MSERGrowthHistory(int size, int value, LinkedImagePoint head) {
this.size = size;
this.maxGreyValue = value;
this.head = head;
this.parent = this;
}
public int getSize() {
return size;
}
public ImagePoint[] getPoints() {
if (points == null) {
points = new ImagePoint[size];
LinkedImagePoint temp = head;
for (int i = 0; i < size; i++) {
points[i] = temp.getPoint();
temp = temp.getNext();
}
}
return points;
}
/**
* Calculate the border from all the points in the shape
*
* @return only the points on the border of the shape
*/
public ImagePoint[] getBorderPoints(int width, int height) {
if (borderPoints == null) {
// point with the smallest index is topLeft
ImagePoint topLeft = null;
HashMap<String, ImagePoint> imagePoints = new HashMap<String, ImagePoint>();
// fill the hash map
for (ImagePoint p : getPoints()) {
if (topLeft == null || topLeft.getIndex() > p.getIndex()) {
topLeft = p;
}
imagePoints.put(p.getX() + "_" + p.getY(), p);
}
List<ImagePoint> boundary = new ArrayList<ImagePoint>();
// begin with topLeft, which is obviously part of the boundary
boundary.add(topLeft);
//examine neighbours in a counterclockwise direction
BoundaryPixel8Edge currentPoint = new BoundaryPixel8Edge(topLeft, width, height, false, imagePoints);
BoundaryPixel8Edge neighbor = currentPoint.getNextBoundary();
// set the stop conditions
ImagePoint stopConditionCurrentPoint = currentPoint.getPoint();
ImagePoint stopConditionNeighborPoint = neighbor.getPoint();
// add the neighbor to the boundary pixels
boundary.add(imagePoints.get(neighbor.getX() + "_" + neighbor.getY()));
// where did the edge come from
neighbor.setCurrentEdge(currentPoint.getNeighbourEdge());
// neighbor is now current point
currentPoint = neighbor;
// get new neighbor
neighbor = currentPoint.getNextBoundary();
while (stopConditionCurrentPoint.getIndex() != currentPoint.getIndex() ||
stopConditionNeighborPoint.getIndex() != neighbor.getIndex()) {
// add the neighbor to the boundary pixels
boundary.add(imagePoints.get(neighbor.getX() + "_" + neighbor.getY()));
// where did the edge come from
neighbor.setCurrentEdge(currentPoint.getNeighbourEdge());
// neighbor is now current point
currentPoint = neighbor;
// get new neighbor
neighbor = currentPoint.getNextBoundary();
}
// -1 because start == last
borderPoints = new ImagePoint[boundary.size()];
boundary.toArray(borderPoints);
}
return borderPoints;
}
public MSERGrowthHistory getParent() {
return parent;
}
public void setIndex(int index) {
this.index = index;
}
public int getIndex() {
return index;
}
public int compareTo(Object o) {
if (maxGreyValue < ((MSERGrowthHistory) o).maxGreyValue) {
return -1;
} else if (maxGreyValue > ((MSERGrowthHistory) o).maxGreyValue) {
return 1;
}
return 0;
}
public static void main(String[] args) {
int[] points = new int[]{12,
21, 22, 23, 25,
30, 31, 32, 33, 34, 35, 36, 38, 39,
40, 41, 42, 43, 44, 45, 48,
50, 51, 53, 54, 55, 56, 58, 59,
63, 64, 65, 66, 67, 68,
71, 72, 73, 74, 75, 76,
80, 81, 82, 83, 84,
91, 92, 93
};
int width = 10;
LinkedImagePoint head = new LinkedImagePoint(new ImagePoint(points[0], width));
LinkedImagePoint last = head;
LinkedImagePoint current;
for (int i = 1; i < points.length; i++) {
current = new LinkedImagePoint(new ImagePoint(points[i], width));
last.setNext(current);
current.setPrev(last);
last = current;
}
MSERGrowthHistory test = new MSERGrowthHistory(49, 36, head);
ImagePoint[] border = test.getBorderPoints(10, 10);
String borderPoints = "";
for (ImagePoint p : border) {
borderPoints += " " + p.getIndex();
}
System.out.println(borderPoints);
// expected border:
String expectedBorderPoints = " 12 21 30 40 50 51 42 53 63 72 71 80 91 92 93 84 75 76 67 68 59 48 39 38 48 58 67 56 45 36 25 34 23 12";
System.out.println(expectedBorderPoints);
System.out.println("SAME =" + ((borderPoints.equals(expectedBorderPoints) ? "true" : "false")));
points = new int[]
{23, 26, 27, 31, 32, 33, 34, 35, 36, 37, 44, 45, 46, 47, 55, 56, 57, 65, 66};
width = 10;
head = new LinkedImagePoint(new ImagePoint(points[0], width));
last = head;
for (int i = 1; i < points.length; i++) {
current = new LinkedImagePoint(new ImagePoint(points[i], width));
last.setNext(current);
current.setPrev(last);
last = current;
}
test = new MSERGrowthHistory(19, 36, head);
border = test.getBorderPoints(width, 10);
borderPoints = "";
for (ImagePoint p : border) {
borderPoints += " " + p.getIndex();
}
System.out.println(borderPoints);
// expected border:
expectedBorderPoints = " 23 32 31 32 33 44 55 65 66 57 47 37 27 26 35 34 23";
System.out.println(expectedBorderPoints);
System.out.println("SAME =" + ((borderPoints.equals(expectedBorderPoints) ? "true" : "false")));
}
}