mirror of
https://github.com/opencv/opencv.git
synced 2025-01-18 22:44:02 +08:00
findChessboardCornersSB: performance + support for full FOV boards with markers
Changes: * UMat for blur + rotate resulting in a speedup of around 2X on an i7 * support for boards larger than specified allowing to cover full FOV * support for markers moving the origin into the center of the board * increase detection accuracy The main change is for supporting boards that are larger than the FOV of the camera and have their origin in the board center. This allows building OEM calibration targets similar to the one from intel real sense utilizing corner points as close as possible to the image border.
This commit is contained in:
parent
bda89a6469
commit
a41cbbdc99
Binary file not shown.
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 33 KiB |
@ -257,7 +257,9 @@ enum { CALIB_CB_ADAPTIVE_THRESH = 1,
|
||||
CALIB_CB_FILTER_QUADS = 4,
|
||||
CALIB_CB_FAST_CHECK = 8,
|
||||
CALIB_CB_EXHAUSTIVE = 16,
|
||||
CALIB_CB_ACCURACY = 32
|
||||
CALIB_CB_ACCURACY = 32,
|
||||
CALIB_CB_LARGER = 64,
|
||||
CALIB_CB_MARKER = 128
|
||||
};
|
||||
|
||||
enum { CALIB_CB_SYMMETRIC_GRID = 1,
|
||||
@ -1237,7 +1239,16 @@ CV_EXPORTS_W bool checkChessboard(InputArray img, Size size);
|
||||
- **CALIB_CB_NORMALIZE_IMAGE** Normalize the image gamma with equalizeHist before detection.
|
||||
- **CALIB_CB_EXHAUSTIVE** Run an exhaustive search to improve detection rate.
|
||||
- **CALIB_CB_ACCURACY** Up sample input image to improve sub-pixel accuracy due to aliasing effects.
|
||||
- **CALIB_CB_LARGER** The detected pattern is allowed to be larger than patternSize (see description).
|
||||
- **CALIB_CB_MARKER** The detected pattern must have a marker (see description).
|
||||
This should be used if an accurate camera calibration is required.
|
||||
@param meta Optional output arrray of detected corners (CV_8UC1 and size = cv::Size(columns,rows)).
|
||||
Each entry stands for one corner of the pattern and can have one of the following values:
|
||||
- 0 = no meta data attached
|
||||
- 1 = left-top corner of a black cell
|
||||
- 2 = left-top corner of a white cell
|
||||
- 3 = left-top corner of a black cell with a white marker dot
|
||||
- 4 = left-top corner of a white cell with a black marker dot (pattern origin in case of markers otherwise first corner)
|
||||
|
||||
The function is analog to findchessboardCorners but uses a localized radon
|
||||
transformation approximated by box filters being more robust to all sort of
|
||||
@ -1248,6 +1259,15 @@ Calibration" demonstrating that the returned sub-pixel positions are more
|
||||
accurate than the one returned by cornerSubPix allowing a precise camera
|
||||
calibration for demanding applications.
|
||||
|
||||
In the case, the flags **CALIB_CB_LARGER** or **CALIB_CB_MARKER** are given,
|
||||
the result can be recovered from the optional meta array. Both flags are
|
||||
helpful to use calibration patterns exceeding the field of view of the camera.
|
||||
These oversized patterns allow more accurate calibrations as corners can be
|
||||
utilized, which are as close as possible to the image borders. For a
|
||||
consistent coordinate system across all images, the optional marker (see image
|
||||
below) can be used to move the origin of the board to the location where the
|
||||
black circle is located.
|
||||
|
||||
@note The function requires a white boarder with roughly the same width as one
|
||||
of the checkerboard fields around the whole board to improve the detection in
|
||||
various environments. In addition, because of the localized radon
|
||||
@ -1257,7 +1277,16 @@ a sample checkerboard optimized for the detection. However, any other checkerboa
|
||||
can be used as well.
|
||||
![Checkerboard](pics/checkerboard_radon.png)
|
||||
*/
|
||||
CV_EXPORTS_W bool findChessboardCornersSB(InputArray image,Size patternSize, OutputArray corners,int flags=0);
|
||||
CV_EXPORTS_AS(findChessboardCornersSBWithMeta)
|
||||
bool findChessboardCornersSB(InputArray image,Size patternSize, OutputArray corners,
|
||||
int flags,OutputArray meta);
|
||||
/** @overload */
|
||||
CV_EXPORTS_W static inline
|
||||
bool findChessboardCornersSB(InputArray image, Size patternSize, OutputArray corners,
|
||||
int flags = 0)
|
||||
{
|
||||
return findChessboardCornersSB(image, patternSize, corners, flags, noArray());
|
||||
}
|
||||
|
||||
//! finds subpixel-accurate positions of the chessboard corners
|
||||
CV_EXPORTS_W bool find4QuadCornerSubpix( InputArray img, InputOutputArray corners, Size region_size );
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -36,7 +36,7 @@ class FastX : public cv::Feature2D
|
||||
branches = 2;
|
||||
min_scale = 2;
|
||||
max_scale = 5;
|
||||
super_resolution = 1;
|
||||
super_resolution = true;
|
||||
filter = true;
|
||||
}
|
||||
};
|
||||
@ -96,7 +96,7 @@ class FastX : public cv::Feature2D
|
||||
void detectImpl(const cv::Mat& _src, std::vector<cv::KeyPoint>& keypoints, const cv::Mat& mask)const;
|
||||
virtual void detectImpl(cv::InputArray image, std::vector<cv::KeyPoint>& keypoints, cv::InputArray mask=cv::noArray())const;
|
||||
|
||||
void rotate(float angle,const cv::Mat &img,cv::Size size,cv::Mat &out)const;
|
||||
void rotate(float angle,cv::InputArray img,cv::Size size,cv::OutputArray out)const;
|
||||
void calcFeatureMap(const cv::Mat &images,cv::Mat& out)const;
|
||||
|
||||
private:
|
||||
@ -111,6 +111,8 @@ class Ellipse
|
||||
public:
|
||||
Ellipse();
|
||||
Ellipse(const cv::Point2f ¢er, const cv::Size2f &axes, float angle);
|
||||
Ellipse(const Ellipse &other);
|
||||
|
||||
|
||||
void draw(cv::InputOutputArray img,const cv::Scalar &color = cv::Scalar::all(120))const;
|
||||
bool contains(const cv::Point2f &pt)const;
|
||||
@ -149,16 +151,18 @@ class Chessboard: public cv::Feature2D
|
||||
int max_tests; //!< maximal number of tested hypothesis
|
||||
bool super_resolution; //!< use super-repsolution for chessboard detection
|
||||
bool larger; //!< indicates if larger boards should be returned
|
||||
bool marker; //!< indicates that valid boards must have a white and black cirlce marker used for orientation
|
||||
|
||||
Parameters()
|
||||
{
|
||||
chessboard_size = cv::Size(9,6);
|
||||
min_scale = 2;
|
||||
min_scale = 3;
|
||||
max_scale = 4;
|
||||
super_resolution = true;
|
||||
max_points = 400;
|
||||
max_tests = 100;
|
||||
max_points = 200;
|
||||
max_tests = 50;
|
||||
larger = false;
|
||||
marker = false;
|
||||
}
|
||||
|
||||
Parameters(int scale,int _max_points):
|
||||
@ -386,6 +390,14 @@ class Chessboard: public cv::Feature2D
|
||||
*/
|
||||
std::vector<cv::Point2f> getCellCenters() const;
|
||||
|
||||
/**
|
||||
* \brief Returns all cells as mats of four points each describing their corners.
|
||||
*
|
||||
* The left top cell has index 0
|
||||
*
|
||||
*/
|
||||
std::vector<cv::Mat> getCells(float shrink_factor = 1.0,bool bwhite=true,bool bblack = true) const;
|
||||
|
||||
/**
|
||||
* \brief Estimates the homography between an ideal board
|
||||
* and reality based on the already recovered points
|
||||
@ -405,6 +417,12 @@ class Chessboard: public cv::Feature2D
|
||||
*/
|
||||
cv::Mat estimateHomography(int field_size = DUMMY_FIELD_SIZE)const;
|
||||
|
||||
/**
|
||||
* \brief Warp image to match ideal checkerboard
|
||||
*
|
||||
*/
|
||||
cv::Mat warpImage(cv::InputArray image)const;
|
||||
|
||||
/**
|
||||
* \brief Returns the size of the board
|
||||
*
|
||||
@ -431,6 +449,11 @@ class Chessboard: public cv::Feature2D
|
||||
*/
|
||||
std::vector<cv::Point2f> getContour()const;
|
||||
|
||||
/**
|
||||
* \brief Masks the found board in the given image
|
||||
*
|
||||
*/
|
||||
void maskImage(cv::InputOutputArray img,const cv::Scalar &color=cv::Scalar::all(0))const;
|
||||
|
||||
/**
|
||||
* \brief Grows the board in all direction until no more corners are found in the feature map
|
||||
@ -467,6 +490,27 @@ class Chessboard: public cv::Feature2D
|
||||
*/
|
||||
bool validateContour()const;
|
||||
|
||||
|
||||
/**
|
||||
\brief delete left column of the board
|
||||
*/
|
||||
bool shrinkLeft();
|
||||
|
||||
/**
|
||||
\brief delete right column of the board
|
||||
*/
|
||||
bool shrinkRight();
|
||||
|
||||
/**
|
||||
\brief shrink first row of the board
|
||||
*/
|
||||
bool shrinkTop();
|
||||
|
||||
/**
|
||||
\brief delete last row of the board
|
||||
*/
|
||||
bool shrinkBottom();
|
||||
|
||||
/**
|
||||
* \brief Grows the board to the left by adding one column.
|
||||
*
|
||||
@ -567,6 +611,12 @@ class Chessboard: public cv::Feature2D
|
||||
*/
|
||||
void normalizeOrientation(bool bblack=true);
|
||||
|
||||
/**
|
||||
* \brief Flips and rotates the board so that the marker
|
||||
* is normalized
|
||||
*/
|
||||
bool normalizeMarkerOrientation();
|
||||
|
||||
/**
|
||||
* \brief Exchanges the stored board with the board stored in other
|
||||
*/
|
||||
@ -594,16 +644,69 @@ class Chessboard: public cv::Feature2D
|
||||
*/
|
||||
std::map<int,int> getMapping()const;
|
||||
|
||||
/**
|
||||
* \brief Estimates rotation of the board around the camera axis
|
||||
*/
|
||||
double estimateRotZ()const;
|
||||
|
||||
/**
|
||||
* \brief Returns true if the cell is black
|
||||
*
|
||||
*/
|
||||
bool isCellBlack(int row,int cola)const;
|
||||
bool isCellBlack(int row,int col)const;
|
||||
|
||||
/**
|
||||
* \brief Returns true if the cell has a round marker at its
|
||||
* center
|
||||
*
|
||||
*/
|
||||
bool hasCellMarker(int row,int col);
|
||||
|
||||
/**
|
||||
* \brief Detects round markers in the chessboard fields based
|
||||
* on the given image and the already recoverd board corners
|
||||
*
|
||||
* \returns Returns the number of found markes
|
||||
*
|
||||
*/
|
||||
int detectMarkers(cv::InputArray image);
|
||||
|
||||
/**
|
||||
* \brief Calculates the average edge sharpness for the chessboard
|
||||
*
|
||||
* \param[in] image The image where the chessboard was detected
|
||||
* \param[in] rise_distante Rise distance 0.8 means 10% ... 90%
|
||||
* \param[in] vertical by default only edge response for horiontal lines are calculated
|
||||
*
|
||||
* \returns Scalar(sharpness, average min_val, average max_val)
|
||||
*
|
||||
* \author aduda@krakenrobotik.de
|
||||
*/
|
||||
cv::Scalar calcEdgeSharpness(cv::InputArray image,float rise_distance=0.8,bool vertical=false,cv::OutputArray sharpness=cv::noArray());
|
||||
|
||||
|
||||
/**
|
||||
* \brief Gets the 3D objects points for the chessboard
|
||||
* assuming the left top corner is located at the origin. In
|
||||
* case the board as a marker, the white marker cell is at position zero
|
||||
*
|
||||
* \param[in] cell_size Size of one cell
|
||||
*
|
||||
* \returns Returns the object points as CV_32FC3
|
||||
*/
|
||||
cv::Mat getObjectPoints(float cell_size)const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Returns the angle the board is rotated agains the x-axis of the image plane
|
||||
* \returns Returns the object points as CV_32FC3
|
||||
*/
|
||||
float getAngle()const;
|
||||
|
||||
/**
|
||||
* \brief Returns true if the main direction of the board is close to the image x-axis than y-axis
|
||||
*/
|
||||
bool isHorizontal()const;
|
||||
|
||||
/**
|
||||
* \brief Updates the search angles
|
||||
*/
|
||||
void setAngles(float white,float black);
|
||||
|
||||
private:
|
||||
// stores one cell
|
||||
@ -616,10 +719,13 @@ class Chessboard: public cv::Feature2D
|
||||
cv::Point2f *top_left,*top_right,*bottom_right,*bottom_left; // corners
|
||||
Cell *left,*top,*right,*bottom; // neighbouring cells
|
||||
bool black; // set to true if cell is black
|
||||
bool marker; // set to true if cell has a round marker in its center
|
||||
Cell();
|
||||
bool empty()const; // indicates if the cell is empty (one of its corners has NaN)
|
||||
int getRow()const;
|
||||
int getCol()const;
|
||||
cv::Point2f getCenter()const;
|
||||
bool isInside(const cv::Point2f &pt)const; // check if point is inside the cell
|
||||
};
|
||||
|
||||
// corners
|
||||
@ -666,8 +772,8 @@ class Chessboard: public cv::Feature2D
|
||||
std::vector<Cell*> cells; // storage for all board cells
|
||||
std::vector<cv::Point2f*> corners; // storage for all corners
|
||||
Cell *top_left; // pointer to the top left corner of the board in its local coordinate system
|
||||
int rows; // number of row cells
|
||||
int cols; // number of col cells
|
||||
int rows; // number of inner pattern rows
|
||||
int cols; // number of inner pattern cols
|
||||
float white_angle,black_angle;
|
||||
};
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user