影子416 2023-02-28 12:54 采纳率: 50%
浏览 56
已结题

关于opencv&c++图片矫正后棋盘周围环境扭曲的现象的原因和解决方法

关于opencv&c++图片矫正后棋盘周围环境扭曲的现象的原因和解决方法。矫正了一张图片,棋盘格内无扭曲,周围环境出现扭曲。
原图:

img


矫正后

img

// CheckerBoardDemo.cpp : 定义控制台应用程序的入口点。
//

//#include <stdafx.h>
#include <opencv2\imgproc\types_c.h>
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;

Mat image, img_gray;
int BOARDSIZE[2]{ 5,7 };//棋盘格每行每列角点个数
int main()
{
    vector<vector<Point3f>> objpoints_img;//保存棋盘格上角点的三维坐标
    vector<Point3f> obj_world_pts;//三维世界坐标
    vector<vector<Point2f>> images_points;//保存所有角点
    vector<Point2f> 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;
}


  • 写回答

1条回答 默认 最新

  • MarkHan_ 2023-02-28 13:12
    关注

    该回答引用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();
    
    
    
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 3月7日
  • 创建了问题 2月28日