use of georegression.struct.point.Point2D_F32 in project BoofCV by lessthanoptimal.
the class ConnectLinesGrid method connectTry.
/**
* See if there is a line that matches in this adjacent region.
*
* @param target Line being connected.
* @param x x-coordinate of adjacent region.
* @param y y-coordinate of adjacent region.
* @return true if a connection was made.
*/
private boolean connectTry(LineSegment2D_F32 target, int x, int y) {
if (!grid.isInBounds(x, y))
return false;
List<LineSegment2D_F32> lines = grid.get(x, y);
int index = findBestCompatible(target, lines, 0);
if (index == -1)
return false;
LineSegment2D_F32 b = lines.remove(index);
// join the two lines by connecting the farthest points from each other
Point2D_F32 pt0 = farthestIndex < 2 ? target.a : target.b;
Point2D_F32 pt1 = (farthestIndex % 2) == 0 ? b.a : b.b;
target.a.set(pt0);
target.b.set(pt1);
// adding the merged one back in allows it to be merged with other lines down
// the line. It will be compared against others in 'target's grid though
lines.add(target);
return true;
}
use of georegression.struct.point.Point2D_F32 in project BoofCV by lessthanoptimal.
the class ConnectLinesGrid method findBestCompatible.
/**
* Searches for a line in the list which the target is compatible with and can
* be connected to.
*
* @param target Line being connected to.
* @param candidates List of candidate lines.
* @param start First index in the candidate list it should start searching at.
* @return Index of the candidate it can connect to. -1 if there is no match.
*/
private int findBestCompatible(LineSegment2D_F32 target, List<LineSegment2D_F32> candidates, int start) {
int bestIndex = -1;
double bestDistance = Double.MAX_VALUE;
int bestFarthest = 0;
float targetAngle = UtilAngle.atanSafe(target.slopeY(), target.slopeX());
float cos = (float) Math.cos(targetAngle);
float sin = (float) Math.sin(targetAngle);
for (int i = start; i < candidates.size(); i++) {
LineSegment2D_F32 c = candidates.get(i);
float angle = UtilAngle.atanSafe(c.slopeY(), c.slopeX());
// see if the two lines have the same slope
if (UtilAngle.distHalf(targetAngle, angle) > lineSlopeAngleTol)
continue;
// see the distance the two lines are apart and if it could be the best line
closestFarthestPoints(target, c);
// two closest end points
Point2D_F32 pt0 = closestIndex < 2 ? target.a : target.b;
Point2D_F32 pt1 = (closestIndex % 2) == 0 ? c.a : c.b;
float xx = pt1.x - pt0.x;
float yy = pt1.y - pt0.y;
float distX = Math.abs(cos * xx - sin * yy);
float distY = Math.abs(cos * yy + sin * xx);
if (distX >= bestDistance || distX > parallelTol || distY > tangentTol)
continue;
// check the angle of the combined line
pt0 = farthestIndex < 2 ? target.a : target.b;
pt1 = (farthestIndex % 2) == 0 ? c.a : c.b;
float angleCombined = UtilAngle.atanSafe(pt1.y - pt0.y, pt1.x - pt0.x);
if (UtilAngle.distHalf(targetAngle, angleCombined) <= lineSlopeAngleTol) {
bestDistance = distX;
bestIndex = i;
bestFarthest = farthestIndex;
}
}
if (bestDistance < parallelTol) {
farthestIndex = bestFarthest;
return bestIndex;
}
return -1;
}
use of georegression.struct.point.Point2D_F32 in project BoofCV by lessthanoptimal.
the class GridRansacLineDetector method convertToLineSegment.
/**
* Lines are found in polar form and this coverts them into line segments by finding
* the extreme points of points on the line.
*
* @param matchSet Set of points belonging to the line.
* @param model Detected line.
* @return Line segement.
*/
private LineSegment2D_F32 convertToLineSegment(List<Edgel> matchSet, LinePolar2D_F32 model) {
float minT = Float.MAX_VALUE;
float maxT = -Float.MAX_VALUE;
LineParametric2D_F32 line = UtilLine2D_F32.convert(model, (LineParametric2D_F32) null);
Point2D_F32 p = new Point2D_F32();
for (Edgel e : matchSet) {
p.set(e.x, e.y);
float t = ClosestPoint2D_F32.closestPointT(line, e);
if (minT > t)
minT = t;
if (maxT < t)
maxT = t;
}
LineSegment2D_F32 segment = new LineSegment2D_F32();
segment.a.x = line.p.x + line.slope.x * minT;
segment.a.y = line.p.y + line.slope.y * minT;
segment.b.x = line.p.x + line.slope.x * maxT;
segment.b.y = line.p.y + line.slope.y * maxT;
return segment;
}
use of georegression.struct.point.Point2D_F32 in project BoofCV by lessthanoptimal.
the class ImageLinePruneMerge method pruneSimilar.
public void pruneSimilar(float toleranceAngle, float toleranceDist, int imgWidth, int imgHeight) {
sortByIntensity();
float[] theta = new float[lines.size()];
List<LineSegment2D_F32> segments = new ArrayList<>(lines.size());
for (int i = 0; i < lines.size(); i++) {
Data d = lines.get(i);
LineParametric2D_F32 l = d.line;
theta[i] = UtilAngle.atanSafe(l.getSlopeY(), l.getSlopeX());
segments.add(LineImageOps.convert(l, imgWidth, imgHeight));
}
for (int i = 0; i < segments.size(); i++) {
LineSegment2D_F32 a = segments.get(i);
if (a == null)
continue;
for (int j = i + 1; j < segments.size(); j++) {
LineSegment2D_F32 b = segments.get(j);
if (b == null)
continue;
// see if they are nearly parallel
if (UtilAngle.distHalf(theta[i], theta[j]) > toleranceAngle)
continue;
Point2D_F32 p = Intersection2D_F32.intersection(a, b, null);
// see if it is nearly parallel and intersects inside the image
if (p != null && p.x >= 0 && p.y >= 0 && p.x < imgWidth && p.y < imgHeight) {
segments.set(j, null);
} else {
// now just see if they are very close
float distA = Distance2D_F32.distance(a, b.a);
float distB = Distance2D_F32.distance(a, b.b);
if (distA <= toleranceDist || distB < toleranceDist) {
segments.set(j, null);
}
}
}
}
List<Data> filtered = new ArrayList<>();
for (int i = 0; i < segments.size(); i++) {
if (segments.get(i) != null) {
filtered.add(lines.get(i));
}
}
lines = filtered;
}
use of georegression.struct.point.Point2D_F32 in project BoofCV by lessthanoptimal.
the class LineImageOps method mergeIntoA.
private static void mergeIntoA(LineSegment2D_F32 a, LineSegment2D_F32 b) {
LineParametric2D_F32 paraA = UtilLine2D_F32.convert(a, (LineParametric2D_F32) null);
Point2D_F32[] pts = new Point2D_F32[4];
float[] t = new float[4];
pts[0] = a.a;
pts[1] = a.b;
pts[2] = b.a;
pts[3] = b.b;
for (int i = 0; i < 4; i++) t[i] = ClosestPoint2D_F32.closestPointT(paraA, pts[i]);
float min = t[0];
float max = min;
int indexMin = 0;
int indexMax = 0;
for (int i = 1; i < 4; i++) {
float v = t[i];
if (v < min) {
min = v;
indexMin = i;
}
if (v > max) {
max = v;
indexMax = i;
}
}
// set the first line to the extreme points on each line
a.a.set(pts[indexMin]);
a.b.set(pts[indexMax]);
}
Aggregations