ser*_*gtk 6 opencv computer-vision
在摄像机校准后,我使用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);
Run Code Online (Sandbox Code Playgroud)
上面的代码dst
包含以下数字后:
-8.82689655e-001 -7.05507338e-001 4.16228324e-001 3.04863811e-001
Run Code Online (Sandbox Code Playgroud)
与数字相比,它们太小了src
.
同时,如果我通过电话取消图像:
cvUndistort2( srcImage, dstImage, &camera1, &dist_coeffs1 );
Run Code Online (Sandbox Code Playgroud)
我收到良好的无失真图像,这意味着与单独的点相比,像素坐标不会如此大幅度地修改.
如何获得与图像相同的特定点的不失真?谢谢.
ser*_*gtk 12
这些点应使用相机矩阵"非标准化".
更具体地说,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;
}
Run Code Online (Sandbox Code Playgroud)
有关OpenCV "相机校准和3D重建"相机矩阵的更多信息
更新:
以下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);
Run Code Online (Sandbox Code Playgroud)