1. 程式人生 > >基於Opencv3.0對影象進行透視變換

基於Opencv3.0對影象進行透視變換

一,計算圖片
垂直拍攝的標定板
垂直拍攝的標定板

傾斜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>

一,計算圖片
垂直拍攝的標定板
垂直拍攝的標定板