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

来源:互联网 发布:js获取数字前两位 编辑:程序博客网 时间:2024/06/06 20:41

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

倾斜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]);        //#######################获取内角点坐标########################################################################    }}

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;}

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);}
阅读全文
0 0
原创粉丝点击