处理相机畸变与偏移矫正(附标定工具)

处理相机畸变与偏移矫正

  • 相机畸变处理与偏移矫正

相机畸变处理与偏移矫正

  • 环境: C++ QT Opencv
  1. 这里已经使用MatLab工具箱,得到了畸变参数xml文件
     Mat img = imread(imgName.toStdString());
        if (img.empty()){
            qDebug() <<"[LOG]preprocess read img is fail."<< imgName;
        }
        imwrite("img_原图.jpg",img);
        // 读取畸变参数
        FileStorage file_xml("data.xml", FileStorage::READ);
        if (!file_xml.isOpened()){
            qDebug()<<"[LOG]Open out_camera_data.xml is fail!";
        }
        Mat camera_matrix;
        Mat distortion_coefficients;
        file_xml["camera_matrix"] >> camera_matrix;
        file_xml["distortion_coefficients"] >> distortion_coefficients;
        file_xml.release();
        // 去畸变
        undistort(img.clone(),img,camera_matrix, distortion_coefficients);
        // 水平翻转
        flip(img.clone(),img,-1);
    
  • 原图:

  • 畸变矫正后:

  1. 偏转矫正(二维码偏转矫正)
    if (all_rect.empty()){
        Mat gray_img;
        cvtColor(img,gray_img,CV_BGR2GRAY);
		// 二值
        threshold(gray_img.clone(),gray_img,0,255,THRESH_BINARY | THRESH_OTSU);
        vector<vector<Point>> contours;
        vector<Vec4i> hierarchy;
        // 找轮廓
        findContours(gray_img, contours, hierarchy, CV_RETR_TREE, CHAIN_APPROX_NONE, Point(0, 0));
       // 寻找三个角点
        for (unsigned int i=0; i<contours.size(); i++){
            if (hierarchy[i][2] != 1){
            	// 是否包含子框
                if (is_father(i, hierarchy)){
                    RotatedRect rotatedRect = minAreaRect(contours[i]);
                    if (rotatedRect.size.width < 30 || rotatedRect.size.height < 30) continue;
                    if (rotatedRect.size.width > 45 || rotatedRect.size.height > 45) continue;
                    Rect rect;
                    rect.x = rotatedRect.center.x;
                    rect.y = rotatedRect.center.y;
                    rect.width = rotatedRect.size.width;
                    rect.height = rotatedRect.size.height;
                    qDebug() << "size: "<< rect.x<< " " << rect.y;
                    all_rect.push_back(rect);
                }
            }
        }

        sort(all_rect.begin(),all_rect.end(),ccmp); //脚点排序
    }
    Point2f src[4]; // 存储四个角点信息
    src[0] = Point(all_rect[0].x - all_rect[0].width/2, all_rect[0].y - all_rect[0].height/2);
    src[1] = Point(all_rect[1].x + all_rect[1].width/2, all_rect[1].y - all_rect[1].height/2);
    src[2] = Point(all_rect[2].x + all_rect[2].width/2, all_rect[2].y + all_rect[2].height/2);
    src[3] = Point(all_rect[0].x - all_rect[0].width/2, all_rect[2].y + all_rect[2].height/2);
//    line(img,src[0],src[1],Scalar(0,255,0),4);
//    line(img,src[1],src[2],Scalar(0,255,0),4);
//    line(img,src[2],src[3],Scalar(0,255,0),4);
//    line(img,src[3],src[0],Scalar(0,255,0),4);

    Point2f dst[4]; // 获取图像变换后位置
    dst[0] = Point(0, 0);
    dst[1] = Point(img.cols, 0);
    dst[2] = Point(img.cols, img.rows);
    dst[3] = Point(0, img.rows);
    Mat M = getPerspectiveTransform(src,dst); //得到变换矩阵
//    Mat rotated;
    warpPerspective(img,result_img,M,img.size()); //opencv 的透视变换
    imwrite("./test_test.jpg",result_img);
}
  • 结果图片

【相机标定工具(单目+双目+matlab)】
链接:https://pan.baidu.com/s/1X00PszoMSI7Zi7nXoEOR7w
提取码:qo8r

你可能感兴趣的:(图像处理,opencv,计算机视觉)