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

boofcv.alg.feature.detect.chess.DetectChessboardFiducial Maven / Gradle / Ivy

/*
 * Copyright (c) 2011-2015, 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.feature.detect.chess;

import boofcv.alg.filter.binary.BinaryImageOps;
import boofcv.alg.filter.binary.GThresholdImageOps;
import boofcv.alg.shapes.polygon.BinaryPolygonConvexDetector;
import boofcv.core.image.GeneralizedImageOps;
import boofcv.struct.image.ImageSingleBand;
import boofcv.struct.image.ImageUInt8;
import georegression.struct.point.Point2D_F64;

import java.util.List;

/**
 * 

* Detects calibration points inside a chessboard calibration target. The image is first the image * is thresholded to create a binary image for square detection, then the binary image is eroded to make sure * the squares don't touch. After that {@link DetectChessSquarePoints} is called and it detects and sorts * the squares. *

*

* The found control points are ensured to be returned in a row-major format with the correct number of rows and columns, * with a counter clockwise ordering. Note that when viewed on the monitor this will appear to be clockwise because * the y-axis points down. If there are multiple valid solution then the solution with the (0,0) grid point closest * top the origin is selected. *

* *

*
* *
* Example of a 5 by 7 grid; column, row. *

* * @author Peter Abeles */ public class DetectChessboardFiducial { // detects the chess board private DetectChessSquarePoints findSeeds; // binary images used to detect chess board private ImageUInt8 binary = new ImageUInt8(1, 1); private ImageUInt8 eroded = new ImageUInt8(1, 1); // Threshold used to create binary image. if < 0 then a threshold a local adaptive threshold is used private double userBinaryThreshold = -1; // parameters for local adaptive threshold private int userAdaptiveRadius = 20; private double userAdaptiveBias = -10; // work space for binary images private T work1; private T work2; /** * Configures detection parameters * * @param numCols Number of columns in the grid. Target dependent. * @param numRows Number of rows in the grid. Target dependent. * @param imageType Type of image being processed */ public DetectChessboardFiducial(int numCols, int numRows, BinaryPolygonConvexDetector detectorSquare, Class imageType) { work1 = GeneralizedImageOps.createSingleBand(imageType, 1, 1); work2 = GeneralizedImageOps.createSingleBand(imageType, 1, 1); // minContourSize is specified later after the image's size is known // TODO make separation configurable? findSeeds = new DetectChessSquarePoints(numCols, numRows,4, detectorSquare); // tell it not to check the edge intensity before it optimizes detectorSquare.setCheckEdgeBefore(false); reset(); } /** * Forgets any past history and resets the detector */ public void reset() { } public boolean process(T gray) { binary.reshape(gray.width, gray.height); eroded.reshape(gray.width, gray.height); if( userBinaryThreshold <= 0 ) { work1.reshape(gray.width,gray.height); work2.reshape(gray.width,gray.height); GThresholdImageOps.adaptiveSquare(gray, binary, userAdaptiveRadius, userAdaptiveBias, true, work1, work2); } else { GThresholdImageOps.threshold(gray, binary, userBinaryThreshold, true); } // erode to make the squares separated BinaryImageOps.erode8(binary, 1, eroded); return findSeeds.process(gray, eroded); } public DetectChessSquarePoints getFindSeeds() { return findSeeds; } public List getCalibrationPoints() { return findSeeds.getCalibrationPoints().toList(); } public ImageUInt8 getBinary() { return eroded; } public void setUserBinaryThreshold(double userBinaryThreshold) { this.userBinaryThreshold = userBinaryThreshold; } public double getUserBinaryThreshold() { return userBinaryThreshold; } public int getUserAdaptiveRadius() { return userAdaptiveRadius; } public void setUserAdaptiveRadius(int userAdaptiveRadius) { this.userAdaptiveRadius = userAdaptiveRadius; } public double getUserAdaptiveBias() { return userAdaptiveBias; } public void setUserAdaptiveBias(double userAdaptiveBias) { this.userAdaptiveBias = userAdaptiveBias; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy