去畸变方法
如图两个公式,直接矫正很好理解,在标定之后得到畸变参数,k,p后依次对原图像像素点代入公式,计算出其正确位置,赋值给新的图像,代码如下:
#include<opencv2/opencv.hpp>
#include<string>
#include <iostream>
using namespace std;
string image_file = "D:\\360MoveData\\Users\\feimaojingzhang\\Desktop\\视觉\\tx\\c1\\28.jpg";
int main(int argc,char **argv)
{
double k1 = 0.024928684812037, k2 = 0.012033182014521, p1 = -2.680375058702241e-04, p2 = 3.382391560956786e-04;
double fx = 2.262872782992156e+03, fy = 2.413405973071257e+03, cx = 1.151552978915428e+03, cy = 1.043331731728508e+03;
cv::Mat image = cv::imread(image_file, 0);
int rows = image.rows, cols = image.cols;
cv::Mat image_undistort = cv::Mat(rows, cols, CV_8UC1);
for (int v = 0; v < rows; v++)
{
for (int u = 0; u < cols; u++) {
double x = (u - cx) / fx, y = (v - cy) / fy;
double r = sqrt(x*x + y * y);
double x_distorted = x * (1 + k1 * r*r + k2 * r*r*r*r) + 2 * p1*x*y + p2 * (r*r + 2 * x*x);
double y_distorted = y * (1 + k1 * r*r + k2 * r*r*r*r) + 2 * p2*x*y + p1 * (r*r + 2 * y*y);
double u_distorted = fx * x_distorted + cx;
double v_distorted = fy * y_distorted + cy;
if (u_distorted >= 0 && v_distorted >= 0 && u_distorted < cols && v_distorted < rows) {
image_undistort.at<uchar>(v,u) = image.at<uchar>((double)v_distorted, (double
)u_distorted);
}
else {
image_undistort.at<uchar>(v, u) = 0;
}
}
}
cv::imshow("distorted", image);
cv::imshow("undistorted", image_undistort);
cv::imwrite("D:\\360MoveData\\Users\\feimaojingzhang\\Desktop\\视觉\\tx\\c1\\b28.jpg", image_undistort);
cv::waitKey();
return 0;
}
这种去畸变方法直接方便好理解,是通过原图像直接投影到去畸变图像,但由于精度问题,总会产生一定空点和条纹,不利于后续求解RT矩阵等一系列操作,而间接纠正法利用反投影,能够避免上述情况的出现。OpenCV中undistorted()函数就是反投影操作。
```cpp
cv::undistorted();