use of net.imglib2.roi.geom.real.Polygon2D in project imagej-ops by imagej.
the class DefaultSmallestEnclosingRectangle method calculate.
@Override
public Polygon2D calculate(final Polygon2D input) {
Polygon2D ch = convexHullFunc.calculate(input);
RealLocalizable cog = centroidFunc.calculate(ch);
Polygon2D minBounds = input;
double minArea = Double.POSITIVE_INFINITY;
// for each edge (i.e. line from P(i-1) to P(i)
for (int i = 1; i < ch.numVertices() - 1; i++) {
final double angle = Math.atan2(ch.vertex(i).getDoublePosition(1) - ch.vertex(i - 1).getDoublePosition(1), ch.vertex(i).getDoublePosition(0) - ch.vertex(i - 1).getDoublePosition(0));
// rotate the polygon in such a manner that the line has an angle of 0
final Polygon2D rotatedPoly = rotate(ch, -angle, cog);
// get the bounds
final Polygon2D bounds = boundingBoxFunc.calculate(rotatedPoly);
// calculate the area of the bounds
final double area = areaFunc.calculate(bounds).get();
// original polygon and save it.
if (area < minArea) {
minArea = area;
minBounds = rotate(bounds, angle, cog);
}
}
// edge (n-1) to 0
final double angle = Math.atan2(ch.vertex(0).getDoublePosition(1) - ch.vertex(ch.numVertices() - 1).getDoublePosition(1), ch.vertex(0).getDoublePosition(0) - ch.vertex(ch.numVertices() - 1).getDoublePosition(0));
// rotate the polygon in such a manner that the line has an angle of 0
final Polygon2D rotatedPoly = rotate(ch, -angle, cog);
// get the bounds
final Polygon2D bounds = boundingBoxFunc.calculate(rotatedPoly);
// calculate the area of the bounds
final double area = areaFunc.calculate(bounds).get();
// original polygon and save it.
if (area < minArea) {
minArea = area;
minBounds = rotate(bounds, angle, cog);
}
return minBounds;
}
use of net.imglib2.roi.geom.real.Polygon2D in project imagej-ops by imagej.
the class DefaultContour method calculate.
@Override
public Polygon2D calculate(final RandomAccessibleInterval<B> input) {
List<RealPoint> p = new ArrayList<>();
final B var = Util.getTypeFromInterval(input).createVariable();
final RandomAccess<B> raInput = Views.extendValue(input, var).randomAccess();
final Cursor<B> cInput = Views.flatIterable(input).cursor();
final ClockwiseMooreNeighborhoodIterator<B> cNeigh = new ClockwiseMooreNeighborhoodIterator<>(raInput);
double[] position = new double[2];
double[] startPos = new double[2];
// find first true pixel
while (cInput.hasNext()) {
// we are looking for a true pixel
if (cInput.next().get()) {
raInput.setPosition(cInput);
raInput.localize(startPos);
// add to polygon
p.add(new RealPoint(startPos[0], startPos[1]));
// backtrack:
raInput.move(-1, 0);
cNeigh.reset();
while (cNeigh.hasNext()) {
if (cNeigh.next().get()) {
boolean specialBacktrack = false;
raInput.localize(position);
if (startPos[0] == position[0] && startPos[1] == position[1]) {
// startPoint was found.
if (useJacobs) {
// Jacobs stopping criteria
final int index = cNeigh.getIndex();
if (index == 1 || index == 0) {
// Jonathans refinement to
// non-terminating jacobs criteria
specialBacktrack = true;
} else if (index == 2 || index == 3) {
// way.
break;
}
// else criteria not fulfilled, continue.
} else {
break;
}
}
// add found point to polygon
p.add(new RealPoint(position[0], position[1]));
if (specialBacktrack) {
cNeigh.backtrackSpecial();
} else {
cNeigh.backtrack();
}
}
}
// we only need to extract one contour.
break;
}
}
return new DefaultWritablePolygon2D(p);
}
use of net.imglib2.roi.geom.real.Polygon2D in project imagej-ops by imagej.
the class DefaultConvexHull2D method calculate.
@Override
public Polygon2D calculate(final Polygon2D input) {
// create a copy of points because se will get resorted, etc.
List<? extends RealLocalizable> RealPoints = new ArrayList<>(GeomUtils.vertices(input));
// Sort RealPoints of P by x-coordinate (in case of a tie, sort by
// y-coordinate).
Collections.sort(RealPoints, new Comparator<RealLocalizable>() {
@Override
public int compare(final RealLocalizable o1, final RealLocalizable o2) {
final Double o1x = new Double(o1.getDoublePosition(0));
final Double o2x = new Double(o2.getDoublePosition(0));
final int result = o1x.compareTo(o2x);
if (result == 0) {
return new Double(o1.getDoublePosition(1)).compareTo(new Double(o2.getDoublePosition(1)));
}
return result;
}
});
// Initialize U and L as empty lists.
// lists will hold vertices of upper and lower hulls
// respectively.
final List<RealLocalizable> U = new ArrayList<>();
final List<RealLocalizable> L = new ArrayList<>();
// build lower hull
for (final RealLocalizable p : RealPoints) {
// turn: remove last RealPoint from L
while (L.size() >= 2 && ccw(L.get(L.size() - 2), L.get(L.size() - 1), p) <= 0) {
L.remove(L.size() - 1);
}
L.add(p);
}
// build upper hull
Collections.reverse(RealPoints);
for (final RealLocalizable p : RealPoints) {
// turn: remove last RealPoint from U
while (U.size() >= 2 && ccw(U.get(U.size() - 2), U.get(U.size() - 1), p) <= 0) {
U.remove(U.size() - 1);
}
U.add(p);
}
// Remove last RealPoint of each list (it's same as first
// RealPoint
// of or list).
L.remove(L.size() - 1);
U.remove(U.size() - 1);
// concatenate L and U
L.addAll(U);
return new DefaultWritablePolygon2D(L);
}
use of net.imglib2.roi.geom.real.Polygon2D in project imagej-ops by imagej.
the class DefaultElongation method compute.
@Override
public void compute(final Polygon2D input, final DoubleType output) {
final List<? extends RealLocalizable> minBB = GeomUtils.vertices(minimumBoundingBoxFunc.calculate(input));
final RealLocalizable p1 = minBB.get(0);
final RealLocalizable p2 = minBB.get(1);
final RealLocalizable p3 = minBB.get(2);
double width = Math.sqrt(Math.pow(p1.getDoublePosition(0) - p2.getDoublePosition(0), 2) + Math.pow(p1.getDoublePosition(1) - p2.getDoublePosition(1), 2));
double length = Math.sqrt(Math.pow(p2.getDoublePosition(0) - p3.getDoublePosition(0), 2) + Math.pow(p2.getDoublePosition(1) - p3.getDoublePosition(1), 2));
if (width > length) {
final double tmp = width;
width = length;
length = tmp;
}
output.set(1d - (width / length));
}
use of net.imglib2.roi.geom.real.Polygon2D in project imagej-ops by imagej.
the class DefaultMinimumFeret method calculate.
@Override
public Pair<RealLocalizable, RealLocalizable> calculate(Polygon2D input) {
final List<? extends RealLocalizable> points = GeomUtils.vertices(function.calculate(input));
double distance = Double.POSITIVE_INFINITY;
RealLocalizable p0 = points.get(0);
RealLocalizable p1 = points.get(0);
double tmpDist = 0;
RealLocalizable tmpP0 = p0;
RealLocalizable tmpP1 = p1;
for (int i = 0; i < points.size() - 2; i++) {
final RealLocalizable lineStart = points.get(i);
final RealLocalizable lineEnd = points.get(i + 1);
tmpDist = 0;
final Line l = new Line(new Vector2D(lineStart.getDoublePosition(0), lineStart.getDoublePosition(1)), new Vector2D(lineEnd.getDoublePosition(0), lineEnd.getDoublePosition(1)), 10e-12);
for (int j = 0; j < points.size(); j++) {
if (j != i && j != i + 1) {
final RealLocalizable ttmpP0 = points.get(j);
final double tmp = l.distance(new Vector2D(ttmpP0.getDoublePosition(0), ttmpP0.getDoublePosition(1)));
if (tmp > tmpDist) {
tmpDist = tmp;
final Vector2D vp = (Vector2D) l.project(new Vector2D(ttmpP0.getDoublePosition(0), ttmpP0.getDoublePosition(1)));
tmpP0 = new RealPoint(vp.getX(), vp.getY());
tmpP1 = ttmpP0;
}
}
}
if (tmpDist < distance) {
distance = tmpDist;
p0 = tmpP0;
p1 = tmpP1;
}
}
final RealLocalizable lineStart = points.get(points.size() - 1);
final RealLocalizable lineEnd = points.get(0);
final Line l = new Line(new Vector2D(lineStart.getDoublePosition(0), lineStart.getDoublePosition(1)), new Vector2D(lineEnd.getDoublePosition(0), lineEnd.getDoublePosition(1)), 10e-12);
tmpDist = 0;
for (int j = 0; j < points.size(); j++) {
if (j != points.size() - 1 && j != 0 + 1) {
final RealLocalizable ttmpP0 = points.get(j);
final double tmp = l.distance(new Vector2D(ttmpP0.getDoublePosition(0), ttmpP0.getDoublePosition(1)));
if (tmp > tmpDist) {
tmpDist = tmp;
final Vector2D vp = (Vector2D) l.project(new Vector2D(ttmpP0.getDoublePosition(0), ttmpP0.getDoublePosition(1)));
tmpP0 = new RealPoint(vp.getX(), vp.getY());
tmpP1 = ttmpP0;
}
}
}
if (tmpDist < distance) {
distance = tmpDist;
p0 = tmpP0;
p1 = tmpP1;
}
return new ValuePair<>(p0, p1);
}
Aggregations