All Downloads are FREE. Search and download functionalities are using the official Maven repository.

boofcv.alg.fiducial.calib.grid.DetectSquareGridFiducial Maven / Gradle / Ivy

Go to download

BoofCV is an open source Java library for real-time computer vision and robotics applications.

There is a newer version: 0.26
Show newest version
/*
 * 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.grid;

import boofcv.abst.filter.binary.InputToBinary;
import boofcv.alg.fiducial.calib.squares.*;
import boofcv.alg.shapes.polygon.BinaryPolygonDetector;
import boofcv.struct.image.GrayU8;
import boofcv.struct.image.ImageGray;
import georegression.struct.point.Point2D_F64;
import georegression.struct.shapes.Polygon2D_F64;
import org.ddogleg.struct.FastQueue;

import java.util.ArrayList;
import java.util.List;

/**
 * Detect a square grid calibration target and returns the corner points of each square.  This calibration grid is
 * specified by a set of squares which are organized in a grid pattern.  All squares are the same size.  The entire
 * grid must be visible.  Space between the squares is specified as a ratio of the square size. The grid will be
 * oriented so that returned points are in counter clockwise (CCW) ordering, which appears to be CW in the image.
 *
 * 

There is also always at least two solutions to the ordering. For sake of consistency it will select * the orientation where index 0 is the closest to the origin.

* *

*
* *
* Example of a 4 by 3 grid (row then column). *

* * @author Peter Abeles */ public class DetectSquareGridFiducial { // dimension of square grid. This only refers to black squares and not the white space int numCols; int numRows; // converts input image into a binary image InputToBinary inputToBinary; // detector for squares BinaryPolygonDetector detectorSquare; // Converts detected squares into a graph and into grids SquaresIntoRegularClusters s2c; RegularClustersIntoGrids c2g; // output results. Grid of calibration points in row-major order List calibrationPoints = new ArrayList(); int calibRows; int calibCols; SquareGridTools tools = new SquareGridTools(); // storage for binary image GrayU8 binary = new GrayU8(1,1); List> clusters; /** * COnfigures the detector * * @param numRows Number of black squares in the grid rows * @param numCols Number of black squares in the grid columns * @param spaceToSquareRatio Ratio of spacing between the squares and the squares width * @param inputToBinary Converts input image into a binary image * @param detectorSquare Detects the squares in the image. Must be configured to detect squares */ public DetectSquareGridFiducial(int numRows, int numCols, double spaceToSquareRatio, InputToBinary inputToBinary , BinaryPolygonDetector detectorSquare) { this.numRows = numRows; this.numCols = numCols; this.inputToBinary = inputToBinary; this.detectorSquare = detectorSquare; s2c = new SquaresIntoRegularClusters(spaceToSquareRatio,Integer.MAX_VALUE, 1.35); c2g = new RegularClustersIntoGrids(numCols*numRows); calibRows = numRows*2; calibCols = numCols*2; } /** * Process the image and detect the calibration target * * @param image Input image * @return true if a calibration target was found and false if not */ public boolean process( T image ) { binary.reshape(image.width,image.height); inputToBinary.process(image,binary); detectorSquare.process(image, binary); FastQueue found = detectorSquare.getFoundPolygons(); clusters = s2c.process(found.toList()); c2g.process(clusters); List grids = c2g.getGrids(); SquareGrid match = null; double matchSize = 0; for( SquareGrid g : grids ) { if (g.columns != numCols || g.rows != numRows) { if( g.columns == numRows && g.rows == numCols ) { tools.transpose(g); } else { continue; } } double size = tools.computeSize(g); if( size > matchSize ) { matchSize = size; match = g; } } if( match != null ) { if( tools.checkFlip(match) ) { tools.flipRows(match); } tools.putIntoCanonical(match); if( !tools.orderSquareCorners(match) ) return false; extractCalibrationPoints(match); return true; } return false; } List row0 = new ArrayList(); List row1 = new ArrayList(); /** * Extracts the calibration points from the corners of a fully ordered grid */ void extractCalibrationPoints(SquareGrid grid) { calibrationPoints.clear(); for (int row = 0; row < grid.rows; row++) { row0.clear(); row1.clear(); for (int col = 0; col < grid.columns; col++) { Polygon2D_F64 square = grid.get(row,col).corners; row0.add(square.get(0)); row0.add(square.get(1)); row1.add(square.get(3)); row1.add(square.get(2)); } calibrationPoints.addAll(row0); calibrationPoints.addAll(row1); } // calibCols = grid.columns*2; // calibRows = grid.rows*2; } public List getCalibrationPoints() { return calibrationPoints; } public int getCalibrationRows() { return calibRows; } public int getCalibrationCols() { return calibCols; } public BinaryPolygonDetector getDetectorSquare() { return detectorSquare; } public List> getClusters() { return clusters; } public SquaresIntoRegularClusters getSquaresIntoClusters() { return s2c; } public RegularClustersIntoGrids getGrids() { return c2g; } public GrayU8 getBinary() { return binary; } public int getColumns() { return numCols; } public int getRows() { return numRows; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy