#include <iostream>
命名空间
{
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 = imread( samples::findFile( imgPath) );
vector<Point2f> corners;
bool found = findChessboardCorners(img, patternSize, corners);
if (!found)
{
cout << "找不到棋盘格角点。" << endl;
return;
}
drawChessboardCorners(img_corners, patternSize, corners, found);
imshow("棋盘格角点检测", 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));
}
FileStorage fs( samples::findFile( intrinsicsPath ), FileStorage::READ);
Mat cameraMatrix, distCoeffs;
fs["camera_matrix"] >> cameraMatrix;
fs["distortion_coefficients"] >> distCoeffs;
vector<Point2f> imagePoints;
undistortPoints(corners, imagePoints, cameraMatrix, distCoeffs);
Mat H = findHomography(objectPointsPlanar, 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));
H /= norm;
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(极分解前):\n" << R << "\ndet(R): " << determinant(R) << endl;
SVDecomp(R, W, U, Vt);
R = U*Vt;
double det = determinant(R);
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(极分解后):\n" << R << "\ndet(R): " << determinant(R) << endl;
Rodrigues(R, rvec);
drawFrameAxes(img_pose, cameraMatrix, distCoeffs, rvec, tvec, 2*squareSize);
imshow("从共面点估计姿态", img_pose);
waitKey();
}
const char* params
= "{ help h | | print usage }"
"{ image | left04.jpg | 棋盘图像路径 }"
"{ intrinsics | left_intrinsics.yml | 相机内参路径 }"
"{ width bw | 9 | 棋盘宽度 }"
"{ height bh | 6 | 棋盘高度 }"
"{ square_size | 0.025 | 棋盘方格大小 }";
}
int main(
int argc,
char *argv[])
{
if (parser.has("help"))
{
parser.about("单应性教程代码。\n"
"示例 1:使用共面点从单应性计算姿态。\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;
}
用于命令行解析。
定义 utility.hpp:890
XML/YAML/JSON 文件存储类,封装了写入或读取所需的所有信息……
定义 persistence.hpp:261
从 Mat 派生的模板矩阵类。
定义 mat.hpp:2247
CV_NODISCARD_STD Mat clone() const
创建数组及其底层数据的完整副本。
Mat col(int x) const
为指定的矩阵列创建一个矩阵头。
Mat cross(InputArray m) const
计算两个 3 元素向量的叉积。
_Tp & at(int i0=0)
返回对指定数组元素的引用。
用于指定其坐标 x、y 和 z 的 3D 点的模板类。
定义 types.hpp:255
用于指定图像或矩形大小的模板类。
定义 types.hpp:335
_Tp height
高度
定义 types.hpp:363
_Tp width
宽度
定义 types.hpp:362
std::string String
定义 cvstd.hpp:151
#define CV_64F
定义 interface.h:79
#define CV_Error(code, msg)
调用错误处理程序。
定义 base.hpp:335
int main(int argc, char *argv[])
定义 highgui_qt.cpp:3