use of boofcv.alg.shapes.ellipse.BinaryEllipseDetector.EllipseInfo in project BoofCV by lessthanoptimal.
the class EllipsesIntoClusters method connect.
/**
* Internal function which connects ellipses together
*/
void connect(List<EllipseInfo> ellipses) {
for (int i = 0; i < ellipses.size(); i++) {
EllipseInfo info1 = ellipses.get(i);
EllipseRotated_F64 e1 = info1.ellipse;
Node node1 = nodes.get(i);
// Only search the maximum of the major axis times two
// add a fudge factor. won't ever be perfect
double maxDistance = e1.a * maxDistanceToMajorAxisRatio;
maxDistance *= maxDistance;
searchResults.reset();
search.findNearest(searchPoints.get(i), maxDistance, Integer.MAX_VALUE, searchResults);
// if this node already has a cluster look it up, otherwise create a new one
List<Node> cluster1;
if (node1.cluster == -1) {
node1.cluster = clusters.size;
cluster1 = clusters.grow();
cluster1.clear();
cluster1.add(node1);
} else {
cluster1 = clusters.get(node1.cluster);
}
double edge1 = info1.averageOutside - info1.averageInside;
// only accept ellipses which have a similar size
for (int j = 0; j < searchResults.size(); j++) {
NnData<Node> d = searchResults.get(j);
EllipseInfo info2 = ellipses.get(d.data.which);
EllipseRotated_F64 e2 = info2.ellipse;
if (e2 == e1)
continue;
// see of they are already connected
if (node1.connections.indexOf(d.data.which) != -1) {
continue;
}
// test the appearance of the ellipses edge
double edge2 = info2.averageOutside - info2.averageInside;
double intensityRatio = Math.abs(edge1 - edge2) / Math.max(edge1, edge2);
if (intensityRatio > edgeIntensitySimilarityTolerance)
continue;
// from the minor axis
if (axisAdjustedDistanceSq(e1, e2) > maxDistance) {
continue;
}
// TODO take in in account how similar their orientation is, but less important when they are circular
// somehow work into aspect ratio test?
// smallest shape divided by largest shape
double ratioA = e1.a > e2.a ? e2.a / e1.a : e1.a / e2.a;
double ratioB = e1.b > e2.b ? e2.b / e1.b : e1.b / e2.b;
if (ratioA < sizeSimilarityTolerance && ratioB < sizeSimilarityTolerance) {
continue;
}
// axis ratio similarity check
double ratioC = (e1.a * e2.b) / (e1.b * e2.a);
if (ratioC > 1)
ratioC = 1.0 / ratioC;
if (ratioC < ratioSimilarityTolerance) {
continue;
}
// Apply rule which combines two features
if (intensityRatio + (1 - ratioC) > (edgeIntensitySimilarityTolerance / 1.5 + (1 - ratioSimilarityTolerance)))
continue;
int indexNode2 = d.data.which;
Node node2 = nodes.get(indexNode2);
// node2 isn't in a cluster already. Add it to this one
if (node2.cluster == -1) {
node2.cluster = node1.cluster;
cluster1.add(node2);
node1.connections.add(indexNode2);
node2.connections.add(i);
} else if (node2.cluster != node1.cluster) {
// Node2 is in a different cluster. Merge the clusters
joinClusters(node1.cluster, node2.cluster);
node1.connections.add(indexNode2);
node2.connections.add(i);
} else {
node1.connections.add(indexNode2);
node2.connections.add(i);
}
}
}
}
use of boofcv.alg.shapes.ellipse.BinaryEllipseDetector.EllipseInfo in project BoofCV by lessthanoptimal.
the class TestEllipsesIntoClusters method create.
private EllipseInfo create(double x0, double y0, double a, double b, double phi) {
EllipseInfo out = new EllipseInfo();
out.ellipse = new EllipseRotated_F64(x0, y0, a, b, phi);
out.averageInside = 10;
out.averageOutside = 200;
out.contour = new ArrayList<>();
return out;
}
Aggregations