use of georegression.struct.point.Point2D_I32 in project BoofCV by lessthanoptimal.
the class PolylineSplitMerge method setSplitVariables.
/**
* Selects and splits the side defined by the e0 corner. If convex a check is performed to
* ensure that the polyline will be convex still.
*/
void setSplitVariables(List<Point2D_I32> contour, Element<Corner> e0, Element<Corner> e1) {
splitter.selectSplitPoint(contour, e0.object.index, e1.object.index, resultsA);
// if convex only perform the split if it would result in a convex polygon
if (convex) {
Point2D_I32 a = contour.get(e0.object.index);
Point2D_I32 b = contour.get(resultsA.index);
Point2D_I32 c = contour.get(next(e0).object.index);
if (UtilPolygons2D_I32.isPositiveZ(a, b, c)) {
e0.object.splitable = false;
return;
}
}
// this function is only called if splitable is set to true so no need to set it again
e0.object.splitLocation = resultsA.index;
e0.object.splitError0 = computeSideError(contour, e0.object.index, resultsA.index);
e0.object.splitError1 = computeSideError(contour, resultsA.index, e1.object.index);
if (e0.object.splitLocation >= contour.size())
throw new RuntimeException("Egads");
}
use of georegression.struct.point.Point2D_I32 in project BoofCV by lessthanoptimal.
the class PolylineSplitMerge method assignLine.
public static void assignLine(List<Point2D_I32> contour, int indexA, int indexB, LineSegment2D_F64 line) {
Point2D_I32 endA = contour.get(indexA);
Point2D_I32 endB = contour.get(indexB);
line.a.set(endA.x, endA.y);
line.b.set(endB.x, endB.y);
}
use of georegression.struct.point.Point2D_I32 in project BoofCV by lessthanoptimal.
the class PolylineSplitMerge method process.
/**
* Process the contour and returns true if a polyline could be found.
* @param contour Contour. Must be a ordered in CW or CCW
* @return true for success or false if one could not be fit
*/
public boolean process(List<Point2D_I32> contour) {
// Reset internal book keeping variables
reset();
if (loops) {
// Reject pathological case
if (contour.size() < 3)
return false;
if (!findInitialTriangle(contour))
return false;
} else {
// Reject pathological case
if (contour.size() < 2)
return false;
// two end points are the seeds. Plus they can't change
addCorner(0);
addCorner(contour.size() - 1);
initializeScore(contour, false);
}
savePolyline();
sequentialSideFit(contour, loops);
if (fatalError)
return false;
int MIN_SIZE = loops ? 3 : 2;
double bestScore = Double.MAX_VALUE;
int bestSize = -1;
for (int i = 0; i < Math.min(maxSides - (MIN_SIZE - 1), polylines.size); i++) {
if (polylines.get(i).score < bestScore) {
bestPolyline = polylines.get(i);
bestScore = bestPolyline.score;
bestSize = i + MIN_SIZE;
}
}
// There was no good match within the min/max size requirement
if (bestSize < minSides) {
return false;
}
// make sure all the sides are within error tolerance
for (int i = 0, j = bestSize - 1; i < bestSize; j = i, i++) {
Point2D_I32 a = contour.get(bestPolyline.splits.get(i));
Point2D_I32 b = contour.get(bestPolyline.splits.get(j));
double length = a.distance(b);
double thresholdSideError = this.maxSideError.compute(length);
if (bestPolyline.sideErrors.get(i) >= thresholdSideError * thresholdSideError) {
bestPolyline = null;
return false;
}
}
return true;
}
use of georegression.struct.point.Point2D_I32 in project BoofCV by lessthanoptimal.
the class PolylineSplitMerge method computeSideError.
/**
* Scores a side based on the sum of Euclidean distance squared of each point along the line. Euclidean squared
* is used because its fast to compute
*
* @param indexA first index. Inclusive
* @param indexB last index. Exclusive
*/
double computeSideError(List<Point2D_I32> contour, int indexA, int indexB) {
assignLine(contour, indexA, indexB, line);
// don't sample the end points because the error will be zero by definition
int numSamples;
double sumOfDistances = 0;
int length;
if (indexB >= indexA) {
length = indexB - indexA - 1;
numSamples = Math.min(length, maxNumberOfSideSamples);
for (int i = 0; i < numSamples; i++) {
int index = indexA + 1 + length * i / numSamples;
Point2D_I32 p = contour.get(index);
sumOfDistances += Distance2D_F64.distanceSq(line, p.x, p.y);
}
sumOfDistances /= numSamples;
} else {
length = contour.size() - indexA - 1 + indexB;
numSamples = Math.min(length, maxNumberOfSideSamples);
for (int i = 0; i < numSamples; i++) {
int where = length * i / numSamples;
int index = (indexA + 1 + where) % contour.size();
Point2D_I32 p = contour.get(index);
sumOfDistances += Distance2D_F64.distanceSq(line, p.x, p.y);
}
sumOfDistances /= numSamples;
}
// handle divide by zero error
if (numSamples > 0)
return sumOfDistances;
else
return 0;
}
use of georegression.struct.point.Point2D_I32 in project BoofCV by lessthanoptimal.
the class PolylineSplitMerge method printCurrent.
private void printCurrent(List<Point2D_I32> contour) {
System.out.print(list.size() + " Indexes[");
Element<Corner> e = list.getHead();
while (e != null) {
System.out.print(" " + e.object.index);
e = e.next;
}
System.out.println(" ]");
System.out.print(" Errors[");
e = list.getHead();
while (e != null) {
String split = e.object.splitable ? "T" : "F";
System.out.print(String.format(" %6.1f %1s", e.object.sideError, split));
e = e.next;
}
System.out.println(" ]");
System.out.print(" Pos[");
e = list.getHead();
while (e != null) {
Point2D_I32 p = contour.get(e.object.index);
System.out.print(String.format(" %3d %3d,", p.x, p.y));
e = e.next;
}
System.out.println(" ]");
}
Aggregations