Search in sources :

Example 11 with RealPoint

use of net.imglib2.RealPoint in project imagej-ops by imagej.

the class DefaultDetectJunctions method filterJunctions.

private void filterJunctions(List<RealPoint> list) {
    // filter out all vaguely similar junction points.
    for (int i = 0; i < list.size() - 1; i++) {
        ArrayList<RealPoint> similars = new ArrayList<>();
        similars.add(list.get(i));
        list.remove(i);
        for (int j = 0; j < list.size(); j++) {
            if (areClose(list.get(j), similars)) {
                similars.add(list.get(j));
                list.remove(j);
                j--;
            }
        }
        if (list.size() > 0)
            list.add(i, averagePoints(similars));
        else
            list.add(averagePoints(similars));
    }
}
Also used : RealPoint(net.imglib2.RealPoint) ArrayList(java.util.ArrayList) RealPoint(net.imglib2.RealPoint)

Example 12 with RealPoint

use of net.imglib2.RealPoint in project imagej-ops by imagej.

the class DefaultDetectRidges method getNextPoint.

/**
 * Recursively determines the next line point and adds it to the running list
 * of line points.
 *
 * @param gradientRA - the {@link RandomAccess} of the gradient image.
 * @param pRA - the {@link RandomAccess} of the eigenvector image.
 * @param nRA - the {@link RandomAccess} of the subpixel line location image.
 * @param points - the {@link ArrayList} containing the line points.
 * @param octant - integer denoting the octant of the last gradient vector,
 *          oriented with 1 being 0 degrees and increasing in the
 *          counterclockwise direction.
 * @param lastnx - the x component of the gradient vector of the last line
 *          point.
 * @param lastny - the y component of the gradient vector of the last line
 *          point.
 * @param lastpx - the x component of the subpixel line location of the last
 *          line point.
 * @param lastpy - the y component of the subpixel line location of the last
 *          line point.
 */
private void getNextPoint(RandomAccess<DoubleType> gradientRA, RandomAccess<DoubleType> pRA, RandomAccess<DoubleType> nRA, List<RealPoint> points, int octant, double lastnx, double lastny, double lastpx, double lastpy) {
    Point currentPos = new Point(gradientRA);
    // variables for the best line point of the three.
    Point salientPoint = new Point(gradientRA);
    double salientnx = 0;
    double salientny = 0;
    double salientpx = 0;
    double salientpy = 0;
    double bestSalience = Double.MAX_VALUE;
    boolean lastPointInLine = true;
    // check the three possible points that could continue the line, starting at
    // the octant after the given octant and rotating clockwise around the
    // current pixel.
    double lastAngle = RidgeDetectionUtils.getAngle(lastnx, lastny);
    for (int i = 1; i < 4; i++) {
        int[] modifier = RidgeDetectionUtils.getOctantCoords(octant + i);
        gradientRA.move(modifier[0], 0);
        gradientRA.move(modifier[1], 1);
        // there.
        if (gradientRA.get().get() > lowerThreshold) /*&& isMaxRA.get().get() > 0*/
        {
            long[] vectorArr = { gradientRA.getLongPosition(0), gradientRA.getLongPosition(1), 0 };
            nRA.setPosition(vectorArr);
            double nx = nRA.get().get();
            nRA.fwd(2);
            double ny = nRA.get().get();
            pRA.setPosition(vectorArr);
            double px = pRA.get().get();
            pRA.fwd(2);
            double py = pRA.get().get();
            double currentAngle = RidgeDetectionUtils.getAngle(nx, ny);
            double subpixelDiff = Math.sqrt(Math.pow(px - lastpx, 2) + Math.pow(py - lastpy, 2));
            double angleDiff = Math.abs(currentAngle - lastAngle);
            lastPointInLine = false;
            // numbers relative to other potential line points.
            if (subpixelDiff + angleDiff < bestSalience) {
                // record the values of the new most salient pixel
                salientPoint = new Point(gradientRA);
                salientnx = nx;
                salientny = ny;
                salientpx = px;
                salientpy = py;
                bestSalience = subpixelDiff + angleDiff;
            }
            // set the values to zero so that they are not added to another line.
            gradientRA.get().set(0);
        }
        // reset our randomAccess for the next check
        gradientRA.setPosition(currentPos);
    }
    // set the current pixel to 0 in the first slice of eigenRA!
    gradientRA.get().setReal(0);
    // find the next line point as long as there is one to find
    if (!lastPointInLine) {
        // take the most salient point
        gradientRA.setPosition(salientPoint);
        points.add(RidgeDetectionUtils.get2DRealPoint(gradientRA.getDoublePosition(0) + salientpx, gradientRA.getDoublePosition(1) + salientpy));
        // the gradient vector itself refers to the greatest change in intensity,
        // and for a pixel on a line this vector will be perpendicular to the
        // direction of the line. But this vector can point to either the left or
        // the right of the line from the perspective of the detector, and there
        // is no guarantee that the vectors at line point will point off the same
        // side of the line. So if they point off different sides, set the current
        // vector by 180 degrees for the purposes of this detector. We set the
        // threshold for angle fixing just above 90 degrees since any lower would
        // prevent ridges curving.
        double potentialGradient = RidgeDetectionUtils.getAngle(salientnx, salientny);
        // even though they are close enough to satisfy.
        if (lastAngle < angleThreshold)
            lastAngle += 360;
        if (potentialGradient < angleThreshold)
            potentialGradient += 360;
        if (Math.abs(potentialGradient - lastAngle) > angleThreshold) {
            salientnx = -salientnx;
            salientny = -salientny;
        }
        // perform the operation again on the new end of the line being formed.
        getNextPoint(gradientRA, pRA, nRA, points, RidgeDetectionUtils.getOctant(salientnx, salientny), salientnx, salientny, salientpx, salientpy);
    }
}
Also used : RealPoint(net.imglib2.RealPoint) Point(net.imglib2.Point) RealPoint(net.imglib2.RealPoint) Point(net.imglib2.Point)

Example 13 with RealPoint

use of net.imglib2.RealPoint 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)

Example 14 with RealPoint

use of net.imglib2.RealPoint 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);
}
Also used : RealPoint(net.imglib2.RealPoint) ArrayList(java.util.ArrayList) RealPoint(net.imglib2.RealPoint) DefaultWritablePolygon2D(net.imglib2.roi.geom.real.DefaultWritablePolygon2D)

Example 15 with RealPoint

use of net.imglib2.RealPoint 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);
}
Also used : RealLocalizable(net.imglib2.RealLocalizable) ArrayList(java.util.ArrayList) DefaultWritablePolygon2D(net.imglib2.roi.geom.real.DefaultWritablePolygon2D)

Aggregations

RealPoint (net.imglib2.RealPoint)21 ArrayList (java.util.ArrayList)9 RealLocalizable (net.imglib2.RealLocalizable)6 DefaultWritablePolygon2D (net.imglib2.roi.geom.real.DefaultWritablePolygon2D)5 Test (org.junit.Test)5 AbstractFeatureTest (net.imagej.ops.features.AbstractFeatureTest)4 Polygon2D (net.imglib2.roi.geom.real.Polygon2D)3 TriangularFacet (net.imagej.ops.geom.geom3d.mesh.TriangularFacet)2 DefaultWritablePolyline (net.imglib2.roi.geom.real.DefaultWritablePolyline)2 Vector3D (org.apache.commons.math3.geometry.euclidean.threed.Vector3D)2 IOException (java.io.IOException)1 URISyntaxException (java.net.URISyntaxException)1 AbstractOpTest (net.imagej.ops.AbstractOpTest)1 DefaultBoundingBox (net.imagej.ops.geom.geom2d.DefaultBoundingBox)1 DefaultConvexHull2D (net.imagej.ops.geom.geom2d.DefaultConvexHull2D)1 DefaultSmallestEnclosingRectangle (net.imagej.ops.geom.geom2d.DefaultSmallestEnclosingRectangle)1 DefaultMesh (net.imagej.ops.geom.geom3d.mesh.DefaultMesh)1 Facet (net.imagej.ops.geom.geom3d.mesh.Facet)1 FinalInterval (net.imglib2.FinalInterval)1 Interval (net.imglib2.Interval)1