use of georegression.struct.line.LineSegment2D_F32 in project BoofCV by lessthanoptimal.
the class VisualizeLineRansac method process.
public void process(BufferedImage image) {
int regionSize = 40;
I input = GeneralizedImageOps.createSingleBand(imageType, image.getWidth(), image.getHeight());
D derivX = GeneralizedImageOps.createSingleBand(derivType, image.getWidth(), image.getHeight());
D derivY = GeneralizedImageOps.createSingleBand(derivType, image.getWidth(), image.getHeight());
GrayF32 edgeIntensity = new GrayF32(input.width, input.height);
GrayF32 suppressed = new GrayF32(input.width, input.height);
GrayF32 orientation = new GrayF32(input.width, input.height);
GrayS8 direction = new GrayS8(input.width, input.height);
GrayU8 detected = new GrayU8(input.width, input.height);
ModelManager<LinePolar2D_F32> manager = new ModelManagerLinePolar2D_F32();
GridLineModelDistance distance = new GridLineModelDistance((float) (Math.PI * 0.75));
GridLineModelFitter fitter = new GridLineModelFitter((float) (Math.PI * 0.75));
ModelMatcher<LinePolar2D_F32, Edgel> matcher = new Ransac<>(123123, manager, fitter, distance, 25, 1);
ImageGradient<I, D> gradient = FactoryDerivative.sobel(imageType, derivType);
System.out.println("Image width " + input.width + " height " + input.height);
ConvertBufferedImage.convertFromSingle(image, input, imageType);
gradient.process(input, derivX, derivY);
GGradientToEdgeFeatures.intensityAbs(derivX, derivY, edgeIntensity);
// non-max suppression on the lines
// GGradientToEdgeFeatures.direction(derivX,derivY,orientation);
// GradientToEdgeFeatures.discretizeDirection4(orientation,direction);
// GradientToEdgeFeatures.nonMaxSuppression4(edgeIntensity,direction,suppressed);
GThresholdImageOps.threshold(edgeIntensity, detected, 30, false);
GridRansacLineDetector<GrayF32> alg = new ImplGridRansacLineDetector_F32(40, 10, matcher);
alg.process((GrayF32) derivX, (GrayF32) derivY, detected);
MatrixOfList<LineSegment2D_F32> gridLine = alg.getFoundLines();
ConnectLinesGrid connect = new ConnectLinesGrid(Math.PI * 0.01, 1, 8);
// connect.process(gridLine);
// LineImageOps.pruneClutteredGrids(gridLine,3);
List<LineSegment2D_F32> found = gridLine.createSingleList();
System.out.println("size = " + found.size());
LineImageOps.mergeSimilar(found, (float) (Math.PI * 0.03), 5f);
// LineImageOps.pruneSmall(found,40);
System.out.println("after size = " + found.size());
ImageLinePanel gui = new ImageLinePanel();
gui.setBackground(image);
gui.setLineSegments(found);
gui.setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
BufferedImage renderedBinary = VisualizeBinaryData.renderBinary(detected, false, null);
ShowImages.showWindow(renderedBinary, "Detected Edges");
ShowImages.showWindow(gui, "Detected Lines");
}
use of georegression.struct.line.LineSegment2D_F32 in project BoofCV by lessthanoptimal.
the class ConnectLinesGrid method connectInSameElement.
/**
* Search for lines in the same region for it to be connected to.
*
* @param lines All the lines in the region.
*/
private void connectInSameElement(List<LineSegment2D_F32> lines) {
for (int i = 0; i < lines.size(); i++) {
LineSegment2D_F32 a = lines.get(i);
int index = findBestCompatible(a, lines, i + 1);
if (index == -1)
continue;
// remove the line from the index which it is being connected to
LineSegment2D_F32 b = lines.remove(index);
// join the two lines by connecting the farthest points from each other
Point2D_F32 pt0 = farthestIndex < 2 ? a.a : a.b;
Point2D_F32 pt1 = (farthestIndex % 2) == 0 ? b.a : b.b;
a.a.set(pt0);
a.b.set(pt1);
}
}
use of georegression.struct.line.LineSegment2D_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.line.LineSegment2D_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.line.LineSegment2D_F32 in project BoofCV by lessthanoptimal.
the class ConnectLinesGrid method connectToNeighbors.
/**
* Connect lines in the target region to lines in neighboring regions. Regions are selected such that
* no two regions are compared against each other more than once.
*
* @param x target region grid x-coordinate
* @param y target region grid y-coordinate
*/
private void connectToNeighbors(int x, int y) {
List<LineSegment2D_F32> lines = grid.get(x, y);
Iterator<LineSegment2D_F32> iter = lines.iterator();
while (iter.hasNext()) {
LineSegment2D_F32 l = iter.next();
boolean connected = false;
if (connectTry(l, x + 1, y))
connected = true;
if (!connected && connectTry(l, x + 1, y + 1))
connected = true;
if (!connected && connectTry(l, x, y + 1))
connected = true;
if (!connected && connectTry(l, x - 1, y + 1))
connected = true;
// remove it to avoid double counting the line
if (connected)
iter.remove();
}
}
Aggregations