Search in sources :

Example 1 with EllipseInfo

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);
            }
        }
    }
}
Also used : EllipseRotated_F64(georegression.struct.curve.EllipseRotated_F64) EllipseInfo(boofcv.alg.shapes.ellipse.BinaryEllipseDetector.EllipseInfo)

Example 2 with EllipseInfo

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;
}
Also used : EllipseRotated_F64(georegression.struct.curve.EllipseRotated_F64) EllipseInfo(boofcv.alg.shapes.ellipse.BinaryEllipseDetector.EllipseInfo)

Aggregations

EllipseInfo (boofcv.alg.shapes.ellipse.BinaryEllipseDetector.EllipseInfo)2 EllipseRotated_F64 (georegression.struct.curve.EllipseRotated_F64)2