/* * 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.circle; import boofcv.alg.fiducial.calib.circle.AsymmetricGridKeyPointDetections.Tangents; import boofcv.alg.fiducial.calib.circle.EllipseClustersIntoAsymmetricGrid.Grid; import georegression.misc.GrlConstants; import georegression.struct.point.Point2D_F64; import georegression.struct.shapes.EllipseRotated_F64; import org.junit.Test; import static org.junit.Assert.assertEquals; /** * @author Peter Abeles */ public class TestAsymmetricGridKeyPointDetections { @Test public void all() { all(3,3); all(4,4); all(4,5); all(5,4); all(5,5); } public void all( int numRows , int numCols ) { AsymmetricGridKeyPointDetections alg = new AsymmetricGridKeyPointDetections(); double r = 0.5; double s = 2.0; Grid grid = createGrid(numRows,numCols,s,r); alg.process(grid); int idx = 0; for (int row = 0; row < numRows; row++) { for (int col = 0; col < numCols; col++) { if( row%2 == 0 && col%2 == 1) continue; if( row%2 == 1 && col%2 == 0) continue; Point2D_F64 p = alg.getKeyPoints().get(idx++); assertEquals(col*s, p.x, GrlConstants.DOUBLE_TEST_TOL); assertEquals(row*s, p.y, GrlConstants.DOUBLE_TEST_TOL); } } } @Test public void horizontal() { horizontal(4,5); horizontal(5,5); horizontal(5,4); } private void horizontal( int numRows , int numCols ) { AsymmetricGridKeyPointDetections alg = new AsymmetricGridKeyPointDetections(); double r = 0.5; double s = 2.0; Grid grid = createGrid(numRows,numCols,s,r); alg.init(grid); alg.horizontal(grid); for (int row = 0; row < grid.rows; row++) { for (int col = 0; col < grid.columns; col++) { int index = grid.getIndexOfEllipse(row,col); if( row%2==0 && col%2==0) { if( col == 0 || col == grid.columns-1-(1-grid.columns%2)) assertEquals(2,alg.tangents.get(index).size); else assertEquals(row+" "+col,4,alg.tangents.get(index).size); } else if( row%2 == 1 && col%2 == 1 ) { if( col == 1 || col == grid.columns-1-(grid.columns%2)) assertEquals(2,alg.tangents.get(index).size); else assertEquals(4,alg.tangents.get(index).size); } } } } @Test public void vertical() { vertical(4,5); vertical(5,5); vertical(5,4); } private void vertical( int numRows , int numCols ) { AsymmetricGridKeyPointDetections alg = new AsymmetricGridKeyPointDetections(); double r = 0.5; double s = 2.0; Grid grid = createGrid(numRows,numCols,s,r); alg.init(grid); alg.vertical(grid); for (int row = 0; row < grid.rows; row++) { for (int col = 0; col < grid.columns; col++) { int index = grid.getIndexOfEllipse(row,col); if( row%2==0 && col%2==0) { if( row == 0 || row == grid.rows-1-(1-grid.rows%2)) assertEquals(2,alg.tangents.get(index).size); else assertEquals(4,alg.tangents.get(index).size); } else if( row%2 == 1 && col%2 == 1 ) { if( row == 1 || row == grid.rows-1-(grid.rows%2)) assertEquals(2,alg.tangents.get(index).size); else assertEquals(4,alg.tangents.get(index).size); } } } } @Test public void diagonalLR() { diagonalLR(4,5); diagonalLR(5,5); diagonalLR(5,4); } private void diagonalLR( int numRows , int numCols ) { AsymmetricGridKeyPointDetections alg = new AsymmetricGridKeyPointDetections(); double r = 0.5; double s = 2.0; Grid grid = createGrid(numRows,numCols,s,r); alg.init(grid); alg.diagonalLR(grid); for (int row = 0; row < grid.rows; row++) { for (int col = 0; col < grid.columns; col++) { if( row%2 == 0 && col%2 == 1) continue; if( row%2 == 1 && col%2 == 0) continue; int index = grid.getIndexOfEllipse(row,col); int expectedNumber = 0; if( col >= 1 && row >= 1 ) expectedNumber += 2; if( col < grid.columns-1 && row < grid.rows-1 ) expectedNumber += 2; assertEquals(expectedNumber,alg.tangents.get(index).size); } } } @Test public void diagonalRL() { diagonalRL(4,5); diagonalRL(5,5); diagonalRL(5,4); } private void diagonalRL( int numRows , int numCols ) { AsymmetricGridKeyPointDetections alg = new AsymmetricGridKeyPointDetections(); double r = 0.5; double s = 2.0; Grid grid = createGrid(numRows,numCols,s,r); alg.init(grid); alg.diagonalRL(grid); for (int row = 0; row < grid.rows; row++) { for (int col = 0; col < grid.columns; col++) { if( row%2 == 0 && col%2 == 1) continue; if( row%2 == 1 && col%2 == 0) continue; int index = grid.getIndexOfEllipse(row,col); int expectedNumber = 0; if( col >= 1 && row < grid.rows-1 ) expectedNumber += 2; if( col < grid.columns-1 && row >= 1 ) expectedNumber += 2; assertEquals(expectedNumber,alg.tangents.get(index).size); } } } @Test public void computeEllipseCenters() { AsymmetricGridKeyPointDetections alg = new AsymmetricGridKeyPointDetections(); Tangents t = alg.tangents.grow(); double r = 2.0; double cx = 2.5; double cy = 3.6; // create line segments from pairs of points along the diameter of a circle for (int i = 0; i < 10; i++) { double theta = Math.PI*i/10.0; double c = Math.cos(theta); double s = Math.sin(theta); t.grow().set( r*c - r*s + cx, r*s + r*c + cy); t.grow().set(-r*c + r*s + cx, -r*s - r*c + cy); } alg.computeEllipseCenters(); assertEquals(1,alg.keypoints.size); assertEquals(cx,alg.keypoints.get(0).x, GrlConstants.DOUBLE_TEST_TOL); assertEquals(cy,alg.keypoints.get(0).y, GrlConstants.DOUBLE_TEST_TOL); } public static Grid createGrid(int numRows , int numCols , double space , double radius ) { Grid grid = new Grid(); grid.rows = numRows; grid.columns = numCols; for (int row = 0; row < numRows; row++) { for (int col = 0; col < numCols; col++) { if( row%2==0 && col%2 == 1) grid.ellipses.add(null); else if( row%2==1 && col%2 == 0) grid.ellipses.add(null); else { double x = col * space; double y = row * space; grid.ellipses.add(new EllipseRotated_F64(x,y,radius,radius,0)); } } } return grid; } }