use of boofcv.alg.feature.detect.chess.ChessboardCorner in project BoofCV by lessthanoptimal.
the class TestChessboardCornerClusterToGrid method convert_extra.
/**
* The input will be a rectangle, but with an extra corner that should be removed
*/
@Test
void convert_extra() {
ChessboardCornerClusterToGrid alg = new ChessboardCornerClusterToGrid();
alg.setRequireCornerSquares(true);
ChessboardCornerGraph graph = new ChessboardCornerGraph();
graph.corners = createGrid(4, 5, true);
// add an extra node to the graph
Node n = graph.corners.get(graph.corners.size - 1);
Node extra = graph.corners.grow();
extra.corner = new ChessboardCorner();
extra.corner.orientation = n.getOrientation() * -1;
extra.corner.x = n.getX() + 30;
extra.corner.y = n.getY();
extra.index = graph.corners.size - 1;
n.edges[0] = extra;
extra.edges[2] = n;
// See if it gets removed
GridInfo info = new GridInfo();
assertTrue(alg.clusterToSparse(graph));
assertTrue(alg.sparseToGrid(info));
assertTrue(info.hasCornerSquare);
assertEquals(5, info.cols);
assertEquals(4, info.rows);
assertEquals(5 * 4, info.nodes.size());
}
use of boofcv.alg.feature.detect.chess.ChessboardCorner in project BoofCV by lessthanoptimal.
the class TestChessboardCornerClusterToGrid method createGrid.
private DogArray<Node> createGrid(int rows, int cols, boolean cornerSquare) {
DogArray<Node> corners = new DogArray<>(Node::new);
// declare the grid
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
Node n = corners.grow();
n.index = row * cols + col;
n.corner = new ChessboardCorner();
n.corner.x = col * 30;
n.corner.y = row * 30;
n.corner.orientation = Math.PI / 4;
if ((row % 2 + col % 2) == 1)
n.corner.orientation -= Math.PI / 2;
if (!cornerSquare)
n.corner.orientation *= -1;
if (row > 0) {
Node p = corners.get((row - 1) * cols + col);
p.edges[1] = n;
n.edges[3] = p;
}
if (col > 0) {
Node p = corners.get(row * cols + col - 1);
p.edges[0] = n;
n.edges[2] = p;
}
}
}
return corners;
}
use of boofcv.alg.feature.detect.chess.ChessboardCorner in project BoofCV by lessthanoptimal.
the class TestChessboardCornerClusterToGrid method sortEdgesCCW_shift.
/**
* Need to shift elements after sorting to ensure edges are every 90 degrees
*/
@Test
void sortEdgesCCW_shift() {
DogArray<Node> corners = new DogArray<>(Node::new);
// Add nodes with 3 edges
for (int jump = 0; jump < 3; jump++) {
Node target = corners.grow();
target.corner = new ChessboardCorner();
target.corner.x = 10;
target.corner.y = 12;
for (int i = 0; i < 3; i++) {
double theta = i * Math.PI / 2;
if (i > jump)
theta += Math.PI / 2;
double c = Math.cos(theta);
double s = Math.sin(theta);
double r = 4;
Node n = new Node();
n.corner = new ChessboardCorner();
n.corner.x = target.getX() + r * c;
n.corner.y = target.getY() + r * s;
target.edges[i] = n;
}
// shuffle to make it a better test
shuffle(target.edges);
}
// add Nodes with two edges
for (int count = 0; count < 10; count++) {
Node target = corners.grow();
target.corner = new ChessboardCorner();
target.corner.x = 10;
target.corner.y = 12;
for (int i = 0; i < 2; i++) {
double theta = i * Math.PI / 2;
double c = Math.cos(theta);
double s = Math.sin(theta);
double r = 4;
Node n = new Node();
n.corner = new ChessboardCorner();
n.corner.x = target.getX() + r * c;
n.corner.y = target.getY() + r * s;
target.edges[i] = n;
}
// shuffle to make it a better test
shuffle(target.edges);
}
ChessboardCornerClusterToGrid alg = new ChessboardCornerClusterToGrid();
alg.sortEdgesCCW(corners);
for (Node n : corners.toList()) {
Node m0 = n.edges[0];
double theta0 = Math.atan2(m0.getY() - n.getY(), m0.getX() - n.getX());
for (int i = 0; i < 4; i++) {
Node m = n.edges[i];
if (m == null)
continue;
double thetaI = Math.atan2(m.getY() - n.getY(), m.getX() - n.getX());
assertEquals(i * Math.PI / 2.0, UtilAngle.distanceCCW(theta0, thetaI), 0.001);
}
}
}
use of boofcv.alg.feature.detect.chess.ChessboardCorner in project BoofCV by lessthanoptimal.
the class TestChessboardCornerClusterToGrid method isRightHanded.
@Test
void isRightHanded() {
Node n = new Node();
n.corner = new ChessboardCorner();
n.corner.x = 10;
n.corner.y = 20;
Node a = new Node();
a.corner = new ChessboardCorner();
Node b = new Node();
b.corner = new ChessboardCorner();
// this will be the column
a.corner.x = n.getX() + 10;
a.corner.y = n.getY();
b.corner.x = n.getX();
// row
b.corner.y = n.getY() + 10;
n.edges[0] = a;
n.edges[1] = b;
assertFalse(ChessboardCornerClusterToGrid.isRightHanded(n, 0, 1));
assertTrue(ChessboardCornerClusterToGrid.isRightHanded(n, 1, 0));
}
use of boofcv.alg.feature.detect.chess.ChessboardCorner in project BoofCV by lessthanoptimal.
the class TestChessboardCornerClusterToGrid method sortEdgesCCW.
@Test
void sortEdgesCCW() {
DogArray<Node> corners = new DogArray<>(Node::new);
for (int nodeIdx = 0; nodeIdx < 6; nodeIdx++) {
Node target = corners.grow();
target.corner = new ChessboardCorner();
target.corner.x = 10;
target.corner.y = 12;
// always 3 edges 90 degrees apart
for (int i = 0; i < 3; i++) {
double theta = -(i + nodeIdx) * Math.PI / 2.0 + nodeIdx;
double c = Math.cos(theta);
double s = Math.sin(theta);
double r = 4;
Node n = new Node();
n.corner = new ChessboardCorner();
n.corner.x = target.getX() + r * c;
n.corner.y = target.getY() + r * s;
target.edges[i + 1] = n;
}
shuffle(target.edges);
}
ChessboardCornerClusterToGrid alg = new ChessboardCornerClusterToGrid();
alg.sortEdgesCCW(corners);
for (Node n : corners.toList()) {
int tested = 0;
for (int i = 0; i < 4; i++) {
int j = (i + 1) % 4;
if (n.edges[i] == null || n.edges[j] == null)
continue;
Node m0 = n.edges[i];
Node m1 = n.edges[j];
double theta0 = Math.atan2(m0.getY() - n.getY(), m0.getX() - n.getX());
double theta1 = Math.atan2(m1.getY() - n.getY(), m1.getX() - n.getX());
double diff = UtilAngle.distanceCCW(theta0, theta1);
assertTrue(UtilAngle.dist(diff, Math.PI / 2.0) < 0.01);
tested++;
}
assertEquals(2, tested);
}
}
Aggregations