use of net.imglib2.roi.util.RealLocalizableRealPositionable in project imagej-ops by imagej.
the class DefaultDetectRidgesTest method RegressionTest.
@Test
public void RegressionTest() {
Img<FloatType> input = generateFloatArrayTestImg(false, 30, 30);
RandomAccess<FloatType> linePainter = input.randomAccess();
// vertical line, then horizontal line
for (int i = 0; i < 2; i++) {
linePainter.setPosition(15, i);
for (int j = 2; j < 12; j++) {
linePainter.setPosition(j, 1 - i);
linePainter.get().set(256);
}
}
// diagonal line
for (int j = 0; j < 10; j++) {
linePainter.setPosition(j, 0);
linePainter.setPosition(j, 1);
linePainter.get().set(256);
}
// circle
int radius = 4, h = 22, k = 22;
for (double a = 0; a < 2 * Math.PI; a += (Math.PI / (4 * radius))) {
linePainter.setPosition(h + (int) Math.round(radius * Math.cos(a)), 0);
linePainter.setPosition(k + (int) Math.round(radius * Math.sin(a)), 1);
linePainter.get().set(256);
}
// run the image through ridge detection
int width = 1, ridgeLengthMin = 4;
double lowerThreshold = 2, higherThreshold = 4;
List<DefaultWritablePolyline> polylines = (List<DefaultWritablePolyline>) ops.run(Ops.Segment.DetectRidges.class, input, width, lowerThreshold, higherThreshold, ridgeLengthMin);
int vertexCount = 0;
for (DefaultWritablePolyline pline : polylines) {
for (int i = 0; i < pline.numVertices(); i++) {
RealLocalizableRealPositionable p = pline.vertex(i);
assertEquals(p.getDoublePosition(0), plineVertices[vertexCount++], 1e-5);
assertEquals(p.getDoublePosition(1), plineVertices[vertexCount++], 1e-5);
}
}
}
use of net.imglib2.roi.util.RealLocalizableRealPositionable in project imagej-ops by imagej.
the class DefaultDetectJunctions method parallelRoutine.
private <L extends RealLocalizable & RealPositionable> void parallelRoutine(RealLocalizableRealPositionable p1, RealLocalizableRealPositionable p2, RealLocalizableRealPositionable q1, RealLocalizableRealPositionable q2, List<RealPoint> junctions, boolean areVertical) {
// find out whether or not they are on the same line
boolean sameLine = false;
if (areVertical && Math.round(p1.getDoublePosition(0)) == Math.round(q1.getDoublePosition(0)))
sameLine = true;
else {
double m = (q2.getDoublePosition(1) - q1.getDoublePosition(1)) / (q2.getDoublePosition(0) - q1.getDoublePosition(0));
double bp = (p2.getDoublePosition(1) - m * p2.getDoublePosition(0));
double bq = (q2.getDoublePosition(1) - m * q2.getDoublePosition(0));
if (bp == bq)
sameLine = true;
}
// there is no junction
if (!sameLine && Math.min(Math.min(getDistance(p1, q1), getDistance(p2, q1)), Math.min(getDistance(p1, q2), getDistance(p2, q2))) > threshold)
return;
int foundJunctions = 0;
double lengthp = getDistance(p1, p2);
double lengthq = getDistance(q1, q2);
// check p1 to be a junction
if ((getDistance(p1, q1) < lengthq && getDistance(p1, q2) < lengthq && sameLine) || Math.min(getDistance(p1, q1), getDistance(p1, q2)) < threshold) {
junctions.add(makeRealPoint(p1));
foundJunctions++;
}
// check p2 to be a junction
if ((getDistance(p2, q1) < lengthq && getDistance(p2, q2) < lengthq && sameLine) || Math.min(getDistance(p2, q1), getDistance(p2, q2)) < threshold) {
junctions.add(makeRealPoint(p2));
foundJunctions++;
}
// check q1 to be a junction
if (((getDistance(q1, p1) < lengthp && getDistance(q1, p2) < lengthp && sameLine) || (Math.min(getDistance(q1, p1), getDistance(q1, p2)) < threshold)) && foundJunctions < 2) {
junctions.add(makeRealPoint(q1));
foundJunctions++;
}
// check q2 to be a junction
if (((getDistance(q2, p1) < lengthp && getDistance(q2, p2) < lengthp && sameLine) || (Math.min(getDistance(q2, p1), getDistance(q2, p2)) < threshold)) && foundJunctions < 2) {
junctions.add(makeRealPoint(q2));
foundJunctions++;
}
}
use of net.imglib2.roi.util.RealLocalizableRealPositionable 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;
}
Aggregations