基于Opencv3.0对图像进行透视变换

版权声明:本文为业余狙击手原创文章,欢迎阅读,欢迎转载,转载请注明出处,谢谢。 https://blog.csdn.net/sxlsxl119/article/details/75087675

一,计算图片
垂直拍摄的标定板
垂直拍摄的标定板

倾斜30度拍摄的标定板
倾斜30度拍摄的标定板

待处理图像
待处理图像

二,矫正效果
矫正效果图
矫正效果图

二,源码
全局变量
//#######################################
std::vector pointsCZ, pointsQX; //垂直,倾斜
//#######################################

1,计算标定板,获取内角点坐标

//标定板内角点计算
void C透视变换Dlg::OnBnClickedButton1()
{

    ofstream oFileExcel1;
    ofstream oFileExcel2;
    string strExcel1 = "D:\\程序测试图片\\7_7自定义标定板2\\垂直30Excel1.csv";
    oFileExcel1.open(strExcel1.c_str(), ios::out | ios::trunc);
    string strExcel2 = "D:\\程序测试图片\\7_7自定义标定板2\\倾斜30Excel2.csv";
    oFileExcel2.open(strExcel2.c_str(), ios::out | ios::trunc);

    cv::Mat  calibmat[2];

    int width, height;

    calibmat[0] = imread("D:\\程序测试图片\\7_7自定义标定板2\\cz16cm0.bmp", 4);
    calibmat[1] = imread("D:\\程序测试图片\\7_7自定义标定板2\\x30_0.bmp", 4);

    width = calibmat[0].cols;
    height = calibmat[0].rows;

    //#######################获取内角点坐标########################################################################
    bool iffindpoint;
    iffindpoint = findChessboardCorners(calibmat[0], cv::Size(7, 9), pointsCZ, CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE + CALIB_CB_FAST_CHECK);
    if (iffindpoint)
    {
        for (int i = 0; i < pointsCZ.size(); i++)
        {
            oFileExcel1 << "[x:y]" << "," << pointsCZ[i].x << "," << pointsCZ[i].y << ",";
            if ((i + 1) % 7 == 0)
            {
                oFileExcel1 << endl;
            }

        }
        oFileExcel1.close();
        drawChessboardCorners(calibmat[0], cv::Size(7, 9), pointsCZ, true); //用于在图片中标记角点 
        imwrite("D:\\程序测试图片\\7_7自定义标定板2\\垂直30.bmp", calibmat[0]);

    }
    iffindpoint = findChessboardCorners(calibmat[1], cv::Size(7, 9), pointsQX, CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE + CALIB_CB_FAST_CHECK);
    if (iffindpoint)
    {
        for (int i = 0; i < pointsQX.size(); i++)
        {
            oFileExcel2 << "[x:y]" << "," << pointsQX[i].x << "," << pointsQX[i].y << ",";
            if ((i + 1) % 7 == 0)
            {
                oFileExcel2 << endl;
            }
        }
        drawChessboardCorners(calibmat[1], cv::Size(7, 9), pointsQX, true); //用于在图片中标记角点 
        imwrite("D:\\程序测试图片\\7_7自定义标定板2\\倾斜30.bmp", calibmat[1]);

        //#######################获取内角点坐标########################################################################
    }
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

2,通过上面获得的对应角点坐标,取其中不在同一平面上的4点计算转换矩阵,并通过转换矩阵矫正图像

//4点透视变换
void C透视变换Dlg::OnBnClickedTestButton()
{

    //###################################################################################################
    //获取映射矩阵
    //###################################################################################################

    // get original image.
    cv::Mat originalImage = cv::imread("D:\\程序测试图片\\7_7自定义标定板2\\dx30_1.bmp", 4);

    // perspective image.
    cv::Mat perspectiveImage;

    // perspective transform
    cv::Point2f objectivePoints[4], imagePoints[4];



    imagePoints[0].x = 923.43; imagePoints[0].y = 1284.55;
    imagePoints[1].x = 938.906; imagePoints[1].y = 857.076;
    imagePoints[2].x = 1590; imagePoints[2].y = 853.5;
    imagePoints[3].x = 1619.71; imagePoints[3].y = 1277.56;


    // objective points of perspective image.
    // move up the perspective image : objectivePoints.y - value .
    // move left the perspective image : objectivePoints.x - value.
    double moveValueX = 0.0;
    double moveValueY = 0.0;


    objectivePoints[0].x = 717.5 + moveValueX; objectivePoints[0].y = 1380.5 + moveValueY;
    objectivePoints[1].x = 714.5 + moveValueX; objectivePoints[1].y = 750.5 + moveValueY;
    objectivePoints[2].x = 1562.82 + moveValueX; objectivePoints[2].y = 745.389 + moveValueY;
    objectivePoints[3].x = 1563.13 + moveValueX; objectivePoints[3].y = 1379.65 + moveValueY;


    //获取转换矩阵                                //原点    //目标点
    cv::Mat transform = cv::getPerspectiveTransform(objectivePoints, imagePoints);

    // 透视变换
    cv::warpPerspective(originalImage,
        perspectiveImage,
        transform,
        cv::Size(originalImage.rows, originalImage.cols),
        cv::INTER_LINEAR | cv::WARP_INVERSE_MAP);

    // cv::imshow("perspective image", perspectiveImage);
    // cvWaitKey(0);
    //cv::imwrite("D:\\程序测试图片\\透视变换原图.bmp", originalImage);
    cv::imwrite("D:\\程序测试图片\\7_7自定义标定板2\\dx30_1透视变换矫正图.bmp", perspectiveImage);

    //return 0;
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

3,通过1计算出的所有角点坐标计算转换矩阵,并通过转换矩阵矫正图像

//多点透视变换
void C透视变换Dlg::OnBnClickedButton2()
{
    //###################################################################################################
    //获取映射矩阵
    //###################################################################################################
    Mat math, origimg, desimg, mask;
    math = cv::findHomography(pointsQX, pointsCZ, mask);
    origimg = imread("D:\\程序测试图片\\7_7自定义标定板2\\y30_0.bmp", 4);//读取垂直标定图像
    //cv::perspectiveTransform(origimg,desimg,math);
    cv::warpPerspective(origimg, desimg, math, Size(origimg.cols, origimg.rows));
    imwrite("D:\\程序测试图片\\7_7自定义标定板2\\y30_0opencv多点矫正.bmp", desimg);
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
					<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-7f770a53f2.css" rel="stylesheet">
            </div>
版权声明:本文为业余狙击手原创文章,欢迎阅读,欢迎转载,转载请注明出处,谢谢。 https://blog.csdn.net/sxlsxl119/article/details/75087675

一,计算图片
垂直拍摄的标定板
垂直拍摄的标定板

猜你喜欢

转载自blog.csdn.net/monk1992/article/details/83657360