Search in sources :

Example 1 with WritablePolyline

use of net.imglib2.roi.geom.real.WritablePolyline in project imagej-ops by imagej.

the class DefaultDetectJunctions method calculate.

@Override
public List<RealPoint> calculate(List<? extends WritablePolyline> input) {
    // output that allows for both split polyline inputs and a
    // realPointCollection for our junctions.
    List<RealPoint> output = new ArrayList<>();
    for (int first = 0; first < input.size() - 1; first++) {
        WritablePolyline firstLine = input.get(first);
        for (int second = first + 1; second < input.size(); second++) {
            WritablePolyline secondLine = input.get(second);
            // interval containing both plines
            Interval intersect = Intervals.intersect(slightlyEnlarge(firstLine, 2), slightlyEnlarge(secondLine, 2));
            // each other.
            if (Intervals.isEmpty(intersect))
                continue;
            // create an arraylist to contain all of the junctions for these two
            // lines (so that we can filter the junctions before putting them in
            // output).
            ArrayList<RealPoint> currentPairJunctions = new ArrayList<>();
            for (int p = 0; p < firstLine.numVertices() - 1; p++) {
                for (int q = 0; q < secondLine.numVertices() - 1; q++) {
                    RealLocalizableRealPositionable p1 = firstLine.vertex(p);
                    RealLocalizableRealPositionable p2 = firstLine.vertex(p + 1);
                    RealLocalizableRealPositionable q1 = secondLine.vertex(q);
                    RealLocalizableRealPositionable q2 = secondLine.vertex(q + 1);
                    // special cases if both lines are vertical
                    boolean pVertical = Math.round(p1.getDoublePosition(0)) == Math.round(p2.getDoublePosition(0));
                    boolean qVertical = Math.round(q1.getDoublePosition(0)) == Math.round(q2.getDoublePosition(0));
                    // intersection point between the lines created by line segments p
                    // and q.
                    double[] intersectionPoint = new double[2];
                    // since they are parallel and cannot be the same.
                    if (pVertical && qVertical) {
                        parallelRoutine(p1, p2, q1, q2, currentPairJunctions, true);
                        continue;
                    } else if (pVertical) {
                        double mq = (q2.getDoublePosition(1) - q1.getDoublePosition(1)) / (q2.getDoublePosition(0) - q1.getDoublePosition(0));
                        double bq = (q1.getDoublePosition(1) - mq * q1.getDoublePosition(0));
                        double x = p1.getDoublePosition(0);
                        double y = mq * x + bq;
                        intersectionPoint[0] = x;
                        intersectionPoint[1] = y;
                    } else if (qVertical) {
                        double mp = (p2.getDoublePosition(1) - p1.getDoublePosition(1)) / (p2.getDoublePosition(0) - p1.getDoublePosition(0));
                        double bp = (p1.getDoublePosition(1) - mp * p1.getDoublePosition(0));
                        double x = q1.getDoublePosition(0);
                        double y = mp * x + bp;
                        intersectionPoint[0] = x;
                        intersectionPoint[1] = y;
                    } else {
                        double mp = (p2.getDoublePosition(1) - p1.getDoublePosition(1)) / (p2.getDoublePosition(0) - p1.getDoublePosition(0));
                        double mq = (q2.getDoublePosition(1) - q1.getDoublePosition(1)) / (q2.getDoublePosition(0) - q1.getDoublePosition(0));
                        if (mp == mq) {
                            parallelRoutine(p1, p2, q1, q2, currentPairJunctions, false);
                            continue;
                        }
                        double bp = (p2.getDoublePosition(1) - mp * p2.getDoublePosition(0));
                        double bq = (q2.getDoublePosition(1) - mq * q2.getDoublePosition(0));
                        // point of intersection of lines created by line segments p and
                        // q.
                        double x = (bq - bp) / (mp - mq);
                        double y = mp * x + bp;
                        intersectionPoint[0] = x;
                        intersectionPoint[1] = y;
                    }
                    // find the distance from the intersection point to both line
                    // segments, and the length of the line segments.
                    double distp1 = getDistance(intersectionPoint, p1);
                    double distp2 = getDistance(intersectionPoint, p2);
                    double distq1 = getDistance(intersectionPoint, q1);
                    double distq2 = getDistance(intersectionPoint, q2);
                    // max distance from line segment to intersection point
                    double maxDist = Math.max(Math.min(distp1, distp2), Math.min(distq1, distq2));
                    // these lines are close enough to form a junction
                    if (maxDist <= threshold)
                        currentPairJunctions.add(new RealPoint(intersectionPoint));
                }
            }
            // filter out the current pair's junctions by removing duplicates and
            // then averaging all remaining nearby junctions
            filterJunctions(currentPairJunctions);
            // add the filtered junctions to the output list.
            for (RealPoint point : currentPairJunctions) output.add(point);
        }
    }
    // filter the junctions -- for each set of junctions that seem vaguely
    // similar, pick out the best one-
    filterJunctions(output);
    return output;
}
Also used : RealLocalizableRealPositionable(net.imglib2.roi.util.RealLocalizableRealPositionable) RealPoint(net.imglib2.RealPoint) ArrayList(java.util.ArrayList) RealPoint(net.imglib2.RealPoint) WritablePolyline(net.imglib2.roi.geom.real.WritablePolyline) RealInterval(net.imglib2.RealInterval) Interval(net.imglib2.Interval)

Example 2 with WritablePolyline

use of net.imglib2.roi.geom.real.WritablePolyline in project imagej-ops by imagej.

the class DefaultDetectRidges method calculate.

@Override
public List<? extends WritablePolyline> calculate(RandomAccessibleInterval<T> input) {
    double sigma = (width / (2 * Math.sqrt(3)));
    // generate the metadata images
    RidgeDetectionMetadata ridgeDetectionMetadata = new RidgeDetectionMetadata(input, sigma, lowerThreshold, higherThreshold);
    // retrieve the metadata images
    Img<DoubleType> p_values = ridgeDetectionMetadata.getPValues();
    Img<DoubleType> n_values = ridgeDetectionMetadata.getNValues();
    Img<DoubleType> gradients = ridgeDetectionMetadata.getGradients();
    // create RandomAccesses for the metadata images
    OutOfBoundsConstantValueFactory<DoubleType, RandomAccessibleInterval<DoubleType>> oscvf = new OutOfBoundsConstantValueFactory<>(new DoubleType(0));
    RandomAccess<DoubleType> pRA = oscvf.create(p_values);
    RandomAccess<DoubleType> nRA = oscvf.create(n_values);
    RandomAccess<DoubleType> gradientRA = oscvf.create(gradients);
    // create the output polyline list.
    List<DefaultWritablePolyline> lines = new ArrayList<>();
    // start at the point of greatest maximum absolute value
    gradientRA.setPosition(RidgeDetectionUtils.getMaxCoords(gradients, true));
    // loop through the maximum values of the image
    while (Math.abs(gradientRA.get().get()) > higherThreshold) {
        // create the List of points that will be used to make the polyline
        List<RealPoint> points = new ArrayList<>();
        // get all of the necessary metadata from the image.
        long[] eigenvectorPos = { gradientRA.getLongPosition(0), gradientRA.getLongPosition(1), 0 };
        // obtain the n-values
        nRA.setPosition(eigenvectorPos);
        double eigenx = nRA.get().getRealDouble();
        nRA.fwd(2);
        double eigeny = nRA.get().getRealDouble();
        // obtain the p-values
        pRA.setPosition(eigenvectorPos);
        double px = pRA.get().getRealDouble();
        pRA.fwd(2);
        double py = pRA.get().getRealDouble();
        // start the list by adding the current point, which is the most line-like
        // point on the polyline
        points.add(RidgeDetectionUtils.get2DRealPoint(gradientRA.getDoublePosition(0) + px, gradientRA.getDoublePosition(1) + py));
        // go in the direction to the left of the perpendicular value
        getNextPoint(gradientRA, pRA, nRA, points, RidgeDetectionUtils.getOctant(eigenx, eigeny), eigenx, eigeny, px, py);
        // flip the array list around so that we get one cohesive line
        gradientRA.setPosition(new long[] { eigenvectorPos[0], eigenvectorPos[1] });
        Collections.reverse(points);
        // go in the opposite direction as before.
        eigenx = -eigenx;
        eigeny = -eigeny;
        getNextPoint(gradientRA, pRA, nRA, points, RidgeDetectionUtils.getOctant(eigenx, eigeny), eigenx, eigeny, px, py);
        // set the value to 0 so that it is not reused.
        gradientRA.get().setReal(0);
        // list has fewer vertices than the parameter, then we do not report it.
        if (points.size() > ridgeLengthMin) {
            DefaultWritablePolyline pline = new DefaultWritablePolyline(points);
            lines.add(pline);
        }
        // find the next max absolute value
        gradientRA.setPosition(RidgeDetectionUtils.getMaxCoords(gradients, true));
    }
    return lines;
}
Also used : DefaultWritablePolyline(net.imglib2.roi.geom.real.DefaultWritablePolyline) ArrayList(java.util.ArrayList) OutOfBoundsConstantValueFactory(net.imglib2.outofbounds.OutOfBoundsConstantValueFactory) RandomAccessibleInterval(net.imglib2.RandomAccessibleInterval) DoubleType(net.imglib2.type.numeric.real.DoubleType) RealPoint(net.imglib2.RealPoint)

Aggregations

ArrayList (java.util.ArrayList)2 RealPoint (net.imglib2.RealPoint)2 Interval (net.imglib2.Interval)1 RandomAccessibleInterval (net.imglib2.RandomAccessibleInterval)1 RealInterval (net.imglib2.RealInterval)1 OutOfBoundsConstantValueFactory (net.imglib2.outofbounds.OutOfBoundsConstantValueFactory)1 DefaultWritablePolyline (net.imglib2.roi.geom.real.DefaultWritablePolyline)1 WritablePolyline (net.imglib2.roi.geom.real.WritablePolyline)1 RealLocalizableRealPositionable (net.imglib2.roi.util.RealLocalizableRealPositionable)1 DoubleType (net.imglib2.type.numeric.real.DoubleType)1