#include <iostream>
namespace
{
enum Pattern { CHESSBOARD, CIRCLES_GRID, ASYMMETRIC_CIRCLES_GRID };
void calcChessboardCorners(
Size boardSize,
float squareSize, vector<Point3f>& corners, Pattern patternType = CHESSBOARD)
{
corners.resize(0);
switch (patternType)
{
case CHESSBOARD:
case CIRCLES_GRID:
for( int i = 0; i < boardSize.height; i++ )
for( int j = 0; j < boardSize.width; j++ )
corners.push_back(
Point3f(
float(j*squareSize),
float(i*squareSize), 0));
break;
case ASYMMETRIC_CIRCLES_GRID:
for( int i = 0; i < boardSize.height; i++ )
for( int j = 0; j < boardSize.width; j++ )
corners.push_back(
Point3f(
float((2*j + i % 2)*squareSize),
float(i*squareSize), 0));
break;
default:
}
}
void poseEstimationFromCoplanarPoints(
const string &imgPath,
const string &intrinsicsPath,
const Size &patternSize,
const float squareSize)
{
Mat img_corners = img.clone(), img_pose = img.clone();
vector<Point2f> corners;
if (!found)
{
cout << "Cannot find chessboard corners." << endl;
return;
}
imshow(
"Chessboard corners detection", img_corners);
vector<Point3f> objectPoints;
calcChessboardCorners(patternSize, squareSize, objectPoints);
vector<Point2f> objectPointsPlanar;
for (size_t i = 0; i < objectPoints.size(); i++)
{
objectPointsPlanar.push_back(
Point2f(objectPoints[i].x, objectPoints[i].y));
}
Mat cameraMatrix, distCoeffs;
fs["camera_matrix"] >> cameraMatrix;
fs["distortion_coefficients"] >> distCoeffs;
vector<Point2f> imagePoints;
cout << "H:\n" << H << endl;
double norm =
sqrt(H.at<
double>(0,0)*H.at<
double>(0,0) +
H.at<double>(1,0)*H.at<double>(1,0) +
H.at<double>(2,0)*H.at<double>(2,0));
Mat c1 = H.col(0);
Mat c2 = H.col(1);
Mat c3 = c1.cross(c2);
Mat tvec = H.col(2);
for (int i = 0; i < 3; i++)
{
R.at<double>(i,0) = c1.at<double>(i,0);
R.at<double>(i,1) = c2.at<double>(i,0);
R.at<double>(i,2) = c3.at<double>(i,0);
}
cout <<
"R (before polar decomposition):\n" << R <<
"\ndet(R): " <<
determinant(R) << endl;
Mat_<double> W, U, Vt;
R = U*Vt;
if (det < 0)
{
Vt.at<double>(2,0) *= -1;
Vt.at<double>(2,1) *= -1;
Vt.at<double>(2,2) *= -1;
R = U*Vt;
}
cout <<
"R (after polar decomposition):\n" << R <<
"\ndet(R): " <<
determinant(R) << endl;
Mat rvec;
drawFrameAxes(img_pose, cameraMatrix, distCoeffs, rvec, tvec, 2*squareSize);
imshow(
"Pose from coplanar points", img_pose);
}
= "{ help h | | print usage }"
"{ image | left04.jpg | path to a chessboard image }"
"{ intrinsics | left_intrinsics.yml | path to camera intrinsics }"
"{ width bw | 9 | chessboard width }"
"{ height bh | 6 | chessboard height }"
"{ square_size | 0.025 | chessboard square size }";
}
int main(
int argc,
char *argv[])
{
CommandLineParser parser(argc, argv,
params);
if (parser.has("help"))
{
parser.about("Code for homography tutorial.\n"
"Example 1: pose from homography with coplanar points.\n");
parser.printMessage();
return 0;
}
Size patternSize(parser.get<
int>(
"width"), parser.get<
int>(
"height"));
float squareSize = (float) parser.get<double>("square_size");
poseEstimationFromCoplanarPoints(parser.get<
String>(
"image"),
parser.get<
String>(
"intrinsics"),
patternSize, squareSize);
return 0;
}
Mat findHomography(InputArray srcPoints, InputArray dstPoints, int method=0, double ransacReprojThreshold=3, OutputArray mask=noArray(), const int maxIters=2000, const double confidence=0.995)
Finds a perspective transformation between two planes.
void undistortPoints(InputArray src, OutputArray dst, InputArray cameraMatrix, InputArray distCoeffs, InputArray R=noArray(), InputArray P=noArray())
Computes the ideal point coordinates from the observed point coordinates.
void Rodrigues(InputArray src, OutputArray dst, OutputArray jacobian=noArray())
Converts a rotation matrix to a rotation vector or vice versa.
void drawChessboardCorners(InputOutputArray image, Size patternSize, InputArray corners, bool patternWasFound)
Renders the detected chessboard corners.
bool findChessboardCorners(InputArray image, Size patternSize, OutputArray corners, int flags=CALIB_CB_ADAPTIVE_THRESH+CALIB_CB_NORMALIZE_IMAGE)
Finds the positions of internal corners of the chessboard.
void drawFrameAxes(InputOutputArray image, InputArray cameraMatrix, InputArray distCoeffs, InputArray rvec, InputArray tvec, float length, int thickness=3)
Draw axes of the world/object coordinate system from pose estimation.
void sqrt(InputArray src, OutputArray dst)
Calculates a square root of array elements.
double norm(InputArray src1, int normType=NORM_L2, InputArray mask=noArray())
Calculates the absolute norm of an array.
void SVDecomp(InputArray src, OutputArray w, OutputArray u, OutputArray vt, int flags=0)
double determinant(InputArray mtx)
Returns the determinant of a square floating-point matrix.
std::string String
Definition: cvstd.hpp:149
Size2i Size
Definition: modules/core/include/opencv2/core/types.hpp:370
Point3_< float > Point3f
Definition: modules/core/include/opencv2/core/types.hpp:290
Point_< float > Point2f
Definition: modules/core/include/opencv2/core/types.hpp:207
#define CV_64F
Definition: core/include/opencv2/core/hal/interface.h:79
cv::String findFile(const cv::String &relative_path, bool required=true, bool silentMode=false)
Try to find requested data file.
#define CV_Error(code, msg)
Call the error handler.
Definition: core/include/opencv2/core/base.hpp:335
void imshow(const String &winname, InputArray mat)
Displays an image in the specified window.
int waitKey(int delay=0)
Waits for a pressed key.
CV_EXPORTS_W Mat imread(const String &filename, int flags=IMREAD_COLOR_BGR)
Loads an image from a file.
int main(int argc, char *argv[])
Definition: highgui_qt.cpp:3
@ StsBadArg
function arg/param is bad
Definition: core/include/opencv2/core/base.hpp:74
PyParams params(const std::string &tag, const std::string &model, const std::string &weights, const std::string &device)
Definition: core/include/opencv2/core.hpp:107