我使用 OpenCV 在相机校准后对一组点进行解畸变。 代码如下。
const int npoints = 2; // number of point specified
// Points initialization.
// Only 2 ponts in this example, in real code they are read from file.
float input_points[npoints][2] = {{0,0}, {2560, 1920}};
CvMat * src = cvCreateMat(1, npoints, CV_32FC2);
CvMat * dst = cvCreateMat(1, npoints, CV_32FC2);
// fill src matrix
float * src_ptr = (float*)src->data.ptr;
for (int pi = 0; pi < npoints; ++pi) {
for (int ci = 0; ci < 2; ++ci) {
*(src_ptr + pi * 2 + ci) = input_points[pi][ci];
}
}
cvUndistortPoints(src, dst, &camera1, &distCoeffs1);
在上面的代码 dst
之后包含以下数字:
-8.82689655e-001 -7.05507338e-001 4.16228324e-001 3.04863811e-001
与 src
中的数字相比太小了。
同时,如果我通过调用取消扭曲图像:
cvUndistort2( srcImage, dstImage, &camera1, &dist_coeffs1 );
我收到了很好的未失真图像,这意味着与单独的点相比,像素坐标没有被大幅修改。
如何对特定点获得与图像相同的不失真? 谢谢。
最佳答案
这些点应该使用相机矩阵“未归一化”。
更具体地说,在调用 cvUndistortPoints
之后还应添加以下转换:
double fx = CV_MAT_ELEM(camera1, double, 0, 0);
double fy = CV_MAT_ELEM(camera1, double, 1, 1);
double cx = CV_MAT_ELEM(camera1, double, 0, 2);
double cy = CV_MAT_ELEM(camera1, double, 1, 2);
float * dst_ptr = (float*)dst->data.ptr;
for (int pi = 0; pi < npoints; ++pi) {
float& px = *(dst_ptr + pi * 2);
float& py = *(dst_ptr + pi * 2 + 1);
// perform transformation.
// In fact this is equivalent to multiplication to camera matrix
px = px * fx + cx;
py = py * fy + cy;
}
有关 OpenCV 相机矩阵的更多信息 'Camera Calibration and 3D Reconstruction'
更新:
以下 C++ 函数调用也应该有效:
std::vector<cv::Point2f> inputDistortedPoints = ...
std::vector<cv::Point2f> outputUndistortedPoints;
cv::Mat cameraMatrix = ...
cv::Mat distCoeffs = ...
cv::undistortPoints(inputDistortedPoints, outputUndistortedPoints, cameraMatrix, distCoeffs, cv::noArray(), cameraMatrix);
关于opencv - 如何对相机拍摄坐标中的点进行反畸变,得到相应的反畸变图像坐标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8499984/