关于opencv&c++图片矫正后棋盘周围环境扭曲的现象的原因和解决方法。矫正了一张图片,棋盘格内无扭曲,周围环境出现扭曲。
原图:
// CheckerBoardDemo.cpp : 定义控制台应用程序的入口点。
//
//#include
#include
#include
#include
using namespace cv;
using namespace std;
Mat image, img_gray;
int BOARDSIZE[2]{ 5,7 };//棋盘格每行每列角点个数
int main()
{
vector> objpoints_img;//保存棋盘格上角点的三维坐标
vector obj_world_pts;//三维世界坐标
vector> images_points;//保存所有角点
vector img_corner_points;//保存每张图检测到的角点
vector<String> images_path;//创建容器存放读取图像路径
string image_path = "E:\\vs\\相机标定\\*.jpg";//待处理图路径 F:/Works/C++/openCV/opencv study/Revise/Revise/Project1/
glob(image_path, images_path);//读取指定文件夹下图像
//转世界坐标系
for (int i = 0; i < BOARDSIZE[1]; i++)
{
for (int j = 0; j < BOARDSIZE[0]; j++)
{
obj_world_pts.push_back(Point3f(j, i, 0));
}
}
for (int i = 0; i < images_path.size(); i++)
{
image = imread(images_path[i]);
cvtColor(image, img_gray, COLOR_BGR2GRAY);
//检测角点
bool found_success = findChessboardCorners(img_gray, Size(BOARDSIZE[0], BOARDSIZE[1]),
img_corner_points,
CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_FAST_CHECK | CALIB_CB_NORMALIZE_IMAGE);
//显示角点
if (found_success)
{
//迭代终止条件
TermCriteria criteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.001);
//进一步提取亚像素角点
cornerSubPix(img_gray, img_corner_points, Size(11, 11),
Size(-1, -1), criteria);
//绘制角点
drawChessboardCorners(image, Size(BOARDSIZE[0], BOARDSIZE[1]), img_corner_points,
found_success);
objpoints_img.push_back(obj_world_pts);//从世界坐标系到相机坐标系
images_points.push_back(img_corner_points);
}
//char *output = "image";
char text[] = "image";
char* output = text;
imshow(output, image);
waitKey(200);
}
/*
计算内参和畸变系数等
*/
Mat cameraMatrix, distCoeffs, R, T;//内参矩阵,畸变系数,旋转量,偏移量
calibrateCamera(objpoints_img, images_points, img_gray.size(),
cameraMatrix, distCoeffs, R, T);
cout << "cameraMatrix:" << endl;
cout << cameraMatrix << endl;
cout << "*****************************" << endl;
cout << "distCoeffs:" << endl;
cout << distCoeffs << endl;
cout << "*****************************" << endl;
cout << "Rotation vector:" << endl;
cout << R << endl;
cout << "*****************************" << endl;
cout << "Translation vector:" << endl;
cout << T << endl;
Mat src, dst;
src = imread("E:\\vs\\相机标定\\1.jpg"); //F:/Works/C++/openCV/opencv study/Revise/image/2.jpg
undistort(src, dst, cameraMatrix, distCoeffs);
char texts[] = "image_dst";
char* dst_output = texts;
//char *dst_output = "image_dst";
namedWindow("out", CV_WINDOW_FREERATIO);
imshow("out", dst);
waitKey(0);
//imwrite("F:/Works/C++/openCV/opencv study/Revise/image/3.jpg", dst);
destroyAllWindows();//销毁显示窗口
system("pause");
return 0;
}
该回答引用GPTᴼᴾᴱᴺᴬᴵ
这个现象可能是因为棋盘周围的环境并不是完全平整的,而且在图像畸变校正之前并没有对其进行处理。这种情况下,校正后图像中的棋盘格会出现扭曲,因为在矫正时算法会假设环境是平整的。
-
要解决这个问题,可以在进行图像畸变校正之前,对图像进行透视变换,以使棋盘周围的环境看起来更加平整。透视变换可以通过寻找图像中的四个角点,并将它们映射到一个平面上来实现。在进行透视变换之后,可以再应用图像畸变校正算法来进一步提高校正的精度。
-
以下是示例代码,其中包括透视变换和图像畸变校正两个步骤:
// 透视变换
vector<Point2f> src_points, dst_points;
src_points.push_back(Point2f(0, 0)); // 左上角
src_points.push_back(Point2f(image.cols - 1, 0)); // 右上角
src_points.push_back(Point2f(0, image.rows - 1)); // 左下角
src_points.push_back(Point2f(image.cols - 1, image.rows - 1)); // 右下角
// 你需要调整的四个点的位置
dst_points.push_back(Point2f(0, 0));
dst_points.push_back(Point2f(image.cols - 1, 0));
dst_points.push_back(Point2f(0, image.rows - 1));
dst_points.push_back(Point2f(image.cols - 1, image.rows - 1));
Mat M = getPerspectiveTransform(src_points, dst_points);
Mat corrected_image;
warpPerspective(image, corrected_image, M, image.size());
// 图像畸变校正
Mat cameraMatrix, distCoeffs;
// 进行相机标定,并获得相机内参和畸变系数
calibrateCamera(objpoints_img, images_points, img_gray.size(),
cameraMatrix, distCoeffs, R, T);
Mat undistorted_image;
undistort(corrected_image, undistorted_image, cameraMatrix, distCoeffs);
// 显示结果
imshow("Undistorted Image", undistorted_image);
waitKey();