/* * Copyright (c) 2011-2016, Peter Abeles. All Rights Reserved. * * This file is part of BoofCV (http://boofcv.org). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package boofcv.alg.fiducial.calib.squares; import georegression.struct.shapes.Polygon2D_F64; import org.junit.Test; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Random; import static org.junit.Assert.*; /** * @author Peter Abeles */ public class TestSquareRegularClustersIntoGrids { public static double DEFAULT_WIDTH = 1.2; Random rand = new Random(23423); @Test public void highLevelCheck() { List<List<SquareNode>> clusters = new ArrayList<>(); for (int length = 1; length <= 4; length++) { clusters.add(createGrid(length, length)); } SquareRegularClustersIntoGrids alg = new SquareRegularClustersIntoGrids(1); alg.process(clusters); assertEquals(4,alg.getGrids().size()); // see if running it twice messes things up alg.process(clusters); assertEquals(4,alg.getGrids().size()); } @Test public void checkNumberOfConnections_positive() { SquareRegularClustersIntoGrids alg = new SquareRegularClustersIntoGrids(1); for (int numRows = 1; numRows <= 4; numRows++) { for (int numCols = 1; numCols <= 4; numCols++) { List<SquareNode> nodes = createGrid(numRows, numCols); Collections.shuffle(nodes, rand); if( numRows == 1 || numCols == 1 ) assertEquals(1,alg.checkNumberOfConnections(nodes)); else assertEquals(2,alg.checkNumberOfConnections(nodes)); } } } @Test public void checkNumberOfConnections_negative() { List<SquareNode> nodes = createGrid(1, 2); nodes.addAll( createGrid(2,3)); SquareRegularClustersIntoGrids alg = new SquareRegularClustersIntoGrids(1); assertEquals(0, alg.checkNumberOfConnections(nodes)); } @Test public void orderInfoLine() { for( int length = 1; length < 4; length++ ) { for (int i = 0; i < 2; i++) { int numRows,numCols; if (i == 0) { numRows = 1; numCols = length; } else { numRows = length; numCols = 1; } List<SquareNode> nodes = createGrid(numRows, numCols); Collections.shuffle(nodes, rand); SquareRegularClustersIntoGrids alg = new SquareRegularClustersIntoGrids(1); alg.orderIntoLine(nodes); SquareGrid found = alg.valid.getTail(); assertEquals(length, found.nodes.size()); if (found.columns == numCols) { assertEquals(numRows, found.rows); } else { assertEquals(numRows, found.columns); assertEquals(numCols, found.rows); } } } } @Test public void orderIntoGrid() { for (int numRows = 2; numRows <= 4; numRows++) { for (int numCols = 2; numCols <= 4; numCols++) { List<SquareNode> nodes = createGrid(numRows, numCols); Collections.shuffle(nodes,rand); SquareRegularClustersIntoGrids alg = new SquareRegularClustersIntoGrids(1); alg.orderIntoGrid(nodes); SquareGrid found = alg.valid.getTail(); assertEquals(numRows*numCols,found.nodes.size()); if( found.columns == numCols ) { assertEquals(numRows,found.rows); } else { assertEquals(numRows,found.columns); assertEquals(numCols,found.rows); } } } } @Test public void addRows() { int numRows = 3; int numCols = 4; List<SquareNode> nodes = createGrid(numRows, numCols); List<SquareNode> column = new ArrayList<>(); for (int i = 0; i < numRows; i++) { column.add( nodes.get(i*numCols)); } List<SquareNode> found = new ArrayList<>(); SquareRegularClustersIntoGrids alg = new SquareRegularClustersIntoGrids(1); assertFalse(alg.addRowsToGrid(column, found)); assertEquals(nodes.size(), found.size()); for (int i = 0; i < found.size(); i++) { assertTrue(nodes.get(i) == found.get(i)); } } @Test public void addLineToGrid() { int numRows = 3; int numCols = 4; List<SquareNode> nodes = createGrid(numRows, numCols); SquareRegularClustersIntoGrids alg = new SquareRegularClustersIntoGrids(1); List<SquareNode> row = new ArrayList<>(); List<SquareNode> col = new ArrayList<>(); checkAddLineToGrid(alg, nodes.get(0), nodes.get(1), row); checkAddLineToGrid(alg, nodes.get(0), nodes.get(numCols), col); assertEquals(numCols - 2, row.size()); assertEquals(numRows - 2, col.size()); assertTrue(row.get(1) == nodes.get(3)); assertTrue(col.get(0) == nodes.get(2 * numCols)); // try it the other direction nodes = createGrid(numRows, numCols); checkAddLineToGrid(alg,nodes.get(numCols - 1), nodes.get(numCols - 2), row); nodes = createGrid(numRows, numCols); checkAddLineToGrid(alg, nodes.get(2 * numCols), nodes.get(1 * numCols), col); assertEquals(numCols - 2, row.size()); assertEquals(numRows - 2, col.size()); } void checkAddLineToGrid(SquareRegularClustersIntoGrids alg, SquareNode a, SquareNode b, List<SquareNode> list) { list.clear(); a.graph = SquareRegularClustersIntoGrids.SEARCHED; b.graph = SquareRegularClustersIntoGrids.SEARCHED; alg.addLineToGrid(a,b,list); } @Test public void pickNot_1() { SquareNode a = new SquareNode(); SquareNode b = new SquareNode(); SquareNode c = new SquareNode(); connect(a, 0, b, 0); connect(a, 1, c, 0); assertTrue(c == SquareRegularClustersIntoGrids.pickNot(a, b)); assertTrue(b == SquareRegularClustersIntoGrids.pickNot(a, c)); } @Test public void pickNot_2() { SquareNode a = new SquareNode(); SquareNode b = new SquareNode(); SquareNode c = new SquareNode(); SquareNode d = new SquareNode(); connect(a,0,b,0); connect(a,1,c,0); connect(a,2,d,0); assertTrue(d == SquareRegularClustersIntoGrids.pickNot(a, b, c)); assertTrue(b == SquareRegularClustersIntoGrids.pickNot(a, c, d)); assertTrue(c == SquareRegularClustersIntoGrids.pickNot(a, d, b)); } public static List<SquareNode> createGrid(int numRows, int numCols) { List<SquareNode> nodes = new ArrayList<>(); double w = DEFAULT_WIDTH; for (int y = 0; y < numRows; y++) { for (int x = 0; x < numCols; x++) { nodes.add( createSquare(x*w*2,y*w*2,w) ); } } int index = 0; for (int y = 0; y < numRows; y++) { for (int x = 0; x < numCols; x++, index++ ) { SquareNode a = nodes.get(index); if( x < numCols-1) { SquareNode b = nodes.get(index + 1); connect(a,0,b,2); } if( y < numRows-1) { SquareNode c = nodes.get(index + numCols); connect(a, 1, c, 3); } } } return nodes; } public static void connect( SquareNode a , int sideA , SquareNode b , int sideB ) { SquareEdge e = new SquareEdge(); e.a = a; e.sideA = sideA; e.b = b; e.sideB = sideB; a.edges[sideA] = e; b.edges[sideB] = e; } public static SquareNode createSquare( double x , double y , double width ) { double r = width/2; Polygon2D_F64 poly = new Polygon2D_F64(4); poly.get(0).set(-r, r); poly.get(1).set( r, r); poly.get(2).set( r,-r); poly.get(3).set(-r,-r); SquareNode square = new SquareNode(); for (int i = 0; i < 4; i++) { poly.get(i).x += x; poly.get(i).y += y; square.sideLengths[i] = width; } square.corners = poly; square.center.set(x,y); square.largestSide = width; return square; } }