攝像機標定+畸變校正

申明:本文摘自網絡:https://blog.csdn.net/Loser__Wang/article/details/51811347

感謝原博主的分享,這裏做一個記錄,以便後續閱讀

摘要:使用MATLAB做攝像機標定,並通過opencv進行校正後的顯示。可以用於相機標定。

一、關於相機的標定

採用Matlab相機標定工具

首先關於校正的基本知識通過OpenCV官網的介紹即可簡單瞭解:

http://docs.opencv.org/2.4/doc/tutorials/calib3d/camera_calibration/camera_calibration.html

對於攝像機我們所關心的主要參數爲攝像機內參,以及幾個畸變係數。上面的連接中後半部分也給瞭如何標定,然而OpenCV自帶的標定程序稍顯繁瑣。因而在本文中我主推使用MATLAB的工具箱。下面讓我們開始標定過程。

標定板

標定的最開始階段最需要的肯定是標定板。兩種方法,直接從opencv官網上能下載到:
http://docs.opencv.org/2.4/_downloads/pattern.png

就是棋盤格

採集數據

那麼有了棋盤格之後自然是需要進行照片了。不多說,直接上程序。按q鍵即可保存圖像,儘量把鏡頭的各個角度都覆蓋好

保存大約15到20張即可。

進行標定

直接而在MATLAB的Command Window裏面輸入cameraCalibrator即可調用標定應用。

首先先把之前照好的圖像添加進去,這是出現:
這裏寫圖片描述
這就是之前讓你記錄的標定板中每個方格的大小。
輸入無誤後就涉及到最關鍵的一步了(MATLAB的這個實在太方便了,都是傻瓜式操作),選擇參數。

爲什麼說他關鍵呢,因爲如果你仔細閱讀了OpenCV的說明之後你會大概明白畸變參數,總共有五個,徑向畸變3個(k1,k2,k3)和切向畸變2個(p1,p2)。


徑向畸變:
x_{corrected}=x(1+k_{1}r^{2}+k_{2}r^{4}+k_{3}r^{6})

y_{corrected}=y(1+k_{1}r^{2}+k_{2}r^{4}+k_{3}r^{6})

 

切向畸變:

x_{corrected}=x+[2p_{1}xy+p_{2}(r^{2}+2x^{2})]

y_{corrected}=y+[p_{1}(r^{2}+2y^{2})+2p_{2}xy]

以及在OpenCV中的畸變係數的排列(這點一定要注意k1,k2,p1,p2,k3),千萬不要以爲k是連着的。
Distortion_{coefficients}=\begin{pmatrix} k_{1} &k_{2} &p_{1} &p_{2} &k_{3} \end{pmatrix}

並且通過實驗表明,三個參數的時候由於k3所對應的非線性較爲劇烈。估計的不好,容易產生極大的扭曲,所以我們在MATLAB中選擇使用兩參數,並且選擇錯切和桶形畸變。


點擊開始後等待一段時間即可完成標定。並且MATLAB給出的可視化還是很不錯的,可以對比校正前後的樣子。


————————————————
版權聲明:本文爲CSDN博主「王強_CASIA」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/Loser__Wang/article/details/51811347

點擊show Undistorted即可看到無畸變的圖像。

到這爲止,你已經完成了標定過程。選擇導出參數,即可把參數進行保存。

保存後可以退出標定應用,在MATLAB主界面中將保存的Mat文件打開。

第二行就是參數

裏面的RadialDistortion對應k1,k2,k3設置爲0了。
TangentialDistortion對應p1,p2。
IntrinsicMatrix對應內參,注意這個和OpenCV中是轉置的關係,注意不要搞錯。


這裏寫圖片描述

對應

OpenCV中查看標定的結果

代碼:

#include "opencv2/opencv.hpp"
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
    VideoCapture inputVideo(0);
    if (!inputVideo.isOpened())
    {
        cout << "Could not open the input video: " << endl;
        return -1;
    }
    Mat frame;
    Mat frameCalibration;

    inputVideo >> frame;
    Mat cameraMatrix = Mat::eye(3, 3, CV_64F);
    cameraMatrix.at<double>(0, 0) = 4.450537506243416e+02;
    cameraMatrix.at<double>(0, 1) = 0.192095145445498;
    cameraMatrix.at<double>(0, 2) = 3.271489590204837e+02;
    cameraMatrix.at<double>(1, 1) = 4.473690628394497e+02;
    cameraMatrix.at<double>(1, 2) = 2.442734958206504e+02;

    Mat distCoeffs = Mat::zeros(5, 1, CV_64F);
    distCoeffs.at<double>(0, 0) = -0.320311439187776;
    distCoeffs.at<double>(1, 0) = 0.117708464407889;
    distCoeffs.at<double>(2, 0) = -0.00548954846049678;
    distCoeffs.at<double>(3, 0) = 0.00141925006352090;
    distCoeffs.at<double>(4, 0) = 0;

    Mat view, rview, map1, map2;
    Size imageSize;
    imageSize = frame.size();
    initUndistortRectifyMap(cameraMatrix, distCoeffs, Mat(),
        getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1, imageSize, 0),
        imageSize, CV_16SC2, map1, map2);


    while (1) //Show the image captured in the window and repeat
    {
        inputVideo >> frame;              // read
        if (frame.empty()) break;         // check if at end
        remap(frame, frameCalibration, map1, map2, INTER_LINEAR);
        imshow("Origianl", frame);
        imshow("Calibration", frameCalibration);
        char key = waitKey(1);
        if (key == 27 || key == 'q' || key == 'Q')break;
    }
    return 0;
}

相信此時你的鏡頭的畸變也得到了修復

 


————————————————
版權聲明:本文爲CSDN博主「王強_CASIA」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/Loser__Wang/article/details/51811347

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章