天天看點

【OpenCV】基于OpenCV的雙目視覺測試 準備環境 雙目标定環節

轉載:http://blog.csdn.net/loser__wang/article/details/52836042

代碼參考鄒宇華老師的雙目,Camera calibration With OpenCV,Camera Calibration and 3D Reconstruction部分,按照自己的情況進行了更改。 

如果讀者是想快速工程使用,那可以看我的這篇部落格,如果想要系統學習,請先看相關教材,并輔以鄒宇華老師的部落格。

準備環境

因為本文是進行雙目立體視覺實驗,是以你必須有兩個攝像頭,單攝像頭标定的實驗可以看我的前一篇文章。解決方案,并且有特别需要注意的點我都會仔細說明。

雙目攝像頭準備

  • 直接購買兩個普通的usb攝像頭,這個方案是我最早采用的,但是遇到不少坑。
    • 注意不要太廣角,因為廣角的畸變會很大,這在後面比對的時候帶來很大的問題
    • 安裝的時候注意把兩個安裝的較為平行,雖然可以矯正出來,但是當然還是自身比較平行的好
    • 同時也要注意兩個攝像頭的軸距,不要太遠或者太近,5-10cm為較為适宜的
    • 分辨率可以高一點,但實驗上我把他限制在320*240,其實可以标定采用高分辨率,比對采用低分辨率
  • 購買淘寶的一種雙目攝像頭
    • 同樣注意是否廣角,這點我覺得有點坑,因為不想涉及到打廣告,淘寶那家內建的很好,但是,最廣角的貌似有點問題,我換成不太廣的了

标定闆準備

  • 淘寶購買标定闆,一個字貴,土豪可以忽略。
  • 自己列印,那麼可以按照我的前一篇文章裡的方法準備,注意記好到底是幾乘幾的。 

    這個幾乘以幾是按照黑白格子的交叉的數量算的,例如,标定闆就是9*6的,記好。

雙目标定環節

最下面給了所有實驗的源代碼,代碼有點亂,還是分開來說。雙目标定環節就是需要得到兩個錄影機各自的内參,以及他們倆的外參數。

雙目錄影機讀取

直接上雙目讀取的代碼,我把兩個攝像頭的分辨率都改了一下。這個得看具體攝像頭的支援程度,有的無法改,你改了也沒效果。

#include "opencv2/opencv.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/highgui.hpp"

using namespace std;
using namespace cv;

int main(){
  VideoCapture camera_l();
  VideoCapture camera_r();
  if (!camera_l.isOpened()) { cout << "No left camera!" << endl; return -; }
  if (!camera_r.isOpened()) { cout << "No right camera!" << endl; return -; }
  camera_l.set(CAP_PROP_FRAME_WIDTH, );
  camera_l.set(CAP_PROP_FRAME_HEIGHT, );
  camera_r.set(CAP_PROP_FRAME_WIDTH, );
  camera_r.set(CAP_PROP_FRAME_HEIGHT, );
  cv::Mat frame_l, frame_r;
  while () {
    camera_l >> frame_l;
    camera_r >> frame_r;
    imshow("Left Camera", frame_l);
    imshow("Right Camera", frame_r);
    char key = waitKey();
    if (key ==  || key == 'q' || key == 'Q') //Allow ESC to quit
      break;
  }
  return ;
}           
  • 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
  • 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

本來雙目錄影機讀取起來并沒有什麼可說的,但是我在後期做别的實驗的時候發現,錄影機有時候讀取的有問題,無法完成初始化,如果确定兩個攝像頭分辨讀取沒有問題,隻是無法一起讀取,有如下兩種解決方案。 

* 鄒老師的方案 

* 在兩個錄影機分别都可以運作之後,我們改變初始化部分的代碼,把兩個if判斷改成如下兩行。

while (!camera_l.isOpened()) { camera_l.open(); };
  while (!camera_r.isOpened()) { camera_r.open(); };           
  • 1
  • 2
  • 1
  • 2

實驗效果如下: 

【OpenCV】基于OpenCV的雙目視覺測試 準備環境 雙目标定環節

注意到,右攝像頭的圖像相對于左攝像頭的圖像有點“左移”。這點自己分析一下原因。很重要,如果不是這項,你下面的工作會白做。因為比對的算法就是遵循這種“左移”的。

标定環節

基本上的流程就是讀取左右攝像頭,分别檢測棋盤的角點,當同時都檢測到完整的角點之後,進行精細化處理,得到更精确地角點并存儲。攢夠一定的數量之後(20-30)之後進行參數計算。并将參數進行存儲。還是直接上代碼,并說明一些實作的細節部分。

請慢慢閱讀。 

一上來的這個ChessboardStable 是用來檢測棋盤格是否穩定的,因為在我的試驗中,雙目攝像頭是用手拿着的,或多或少會有一些抖動,這樣如果隻是檢測是否存在角點,可能會通過不是很清晰穩定的圖像進行分析,這樣會帶來比較大的誤差,如果通過一個隊列判斷是否穩定,則可以避免這種誤差。我是簡單粗暴的使用vector代替隊列的。 

後面的部分需要注意的就是boardSize,squareSize 需要設定為你的标定闆對應的尺寸,我拿A4紙簡單的列印的一份,每個格子的大小經過測量時26mm,你可以根據你自己的标定闆進行相應的設定。

#include <string>
#include <stdio.h>
#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace std;
using namespace cv;

vector<vector<Point2f> >corners_l_array, corners_r_array;
int array_index = ;
bool ChessboardStable(vector<Point2f>corners_l, vector<Point2f>corners_r){
  if (corners_l_array.size() < ){
    corners_l_array.push_back(corners_l);
    corners_r_array.push_back(corners_r);
    return false;
  }
  else{
    corners_l_array[array_index % ] = corners_l;
    corners_r_array[array_index % ] = corners_r;
    array_index++;
    double error = ;
    for (int i = ; i < corners_l_array.size(); i++){
      for (int j = ; j < corners_l_array[i].size(); j++){
        error += abs(corners_l[j].x - corners_l_array[i][j].x) + abs(corners_l[j].y - corners_l_array[i][j].y);
        error += abs(corners_r[j].x - corners_r_array[i][j].x) + abs(corners_r[j].y - corners_r_array[i][j].y);
      }
    }
    if (error < )
    {
      corners_l_array.clear();
      corners_r_array.clear();
      array_index = ;
      return true;
    }
    else
      return false;
  }
}


int main(){
  VideoCapture camera_l();
  VideoCapture camera_r();

  while (!camera_l.isOpened()) { camera_l.open(); };
  while (!camera_r.isOpened()) { camera_r.open(); };
  camera_l.set(CAP_PROP_FRAME_WIDTH, );
  camera_l.set(CAP_PROP_FRAME_HEIGHT, );
  camera_r.set(CAP_PROP_FRAME_WIDTH, );
  camera_r.set(CAP_PROP_FRAME_HEIGHT, );

  Mat frame_l, frame_r;

  Size boardSize(, );
  const float squareSize = ;  // Set this to your actual square size

  vector<vector<Point2f> > imagePoints_l;
  vector<vector<Point2f> > imagePoints_r;



  int nimages = ;

  while (){
    camera_l >> frame_l;
    camera_r >> frame_r;

    bool found_l = false, found_r = false;

    vector<Point2f>corners_l, corners_r;
    found_l = findChessboardCorners(frame_l, boardSize, corners_l,
      CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_NORMALIZE_IMAGE);
    found_r = findChessboardCorners(frame_r, boardSize, corners_r,
      CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_NORMALIZE_IMAGE);


    if (found_l && found_r &&ChessboardStable(corners_l, corners_r)) {
      Mat viewGray;
      cvtColor(frame_l, viewGray, COLOR_BGR2GRAY);
      cornerSubPix(viewGray, corners_l, Size(, ),
        Size(-, -), TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, , ));
      cvtColor(frame_r, viewGray, COLOR_BGR2GRAY);
      cornerSubPix(viewGray, corners_r, Size(, ),
        Size(-, -), TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, , ));

      imagePoints_l.push_back(corners_l);
      imagePoints_r.push_back(corners_r);
      ++nimages;
      frame_l += ;
      frame_r += ;

      drawChessboardCorners(frame_l, boardSize, corners_l, found_l);
      drawChessboardCorners(frame_r, boardSize, corners_r, found_r);

      putText(frame_l, to_string(nimages), Point(, ), , , Scalar(, , ));
      putText(frame_r, to_string(nimages), Point(, ), , , Scalar(, , ));
      imshow("Left Camera", frame_l);
      imshow("Right Camera", frame_r);
      char c = (char)waitKey();
      if (c ==  || c == 'q' || c == 'Q') //Allow ESC to quit
        exit(-);

      if (nimages >= )
        break;
    }
    else{
      drawChessboardCorners(frame_l, boardSize, corners_l, found_l);
      drawChessboardCorners(frame_r, boardSize, corners_r, found_r);

      putText(frame_l, to_string(nimages), Point(, ), , , Scalar(, , ));
      putText(frame_r, to_string(nimages), Point(, ), , , Scalar(, , ));
      imshow("Left Camera", frame_l);
      imshow("Right Camera", frame_r);

      char key = waitKey();
      if (key == )
        break;
    }


  }
  if (nimages < ){ cout << "Not enough" << endl; return -; }

  vector<vector<Point2f> > imagePoints[] = { imagePoints_l, imagePoints_r };
  vector<vector<Point3f> > objectPoints;
  objectPoints.resize(nimages);

  for (int i = ; i < nimages; i++)
  {
    for (int j = ; j < boardSize.height; j++)
    for (int k = ; k < boardSize.width; k++)
      objectPoints[i].push_back(Point3f(k*squareSize, j*squareSize, ));
  }

  cout << "Running stereo calibration ..." << endl;

  Size imageSize(, );

  Mat cameraMatrix[], distCoeffs[];
  cameraMatrix[] = initCameraMatrix2D(objectPoints, imagePoints_l, imageSize, );
  cameraMatrix[] = initCameraMatrix2D(objectPoints, imagePoints_r, imageSize, );
  Mat R, T, E, F;

  double rms = stereoCalibrate(objectPoints, imagePoints_l, imagePoints_r,
    cameraMatrix[], distCoeffs[],
    cameraMatrix[], distCoeffs[],
    imageSize, R, T, E, F,
    CALIB_FIX_ASPECT_RATIO +
    CALIB_ZERO_TANGENT_DIST +
    CALIB_USE_INTRINSIC_GUESS +
    CALIB_SAME_FOCAL_LENGTH +
    CALIB_RATIONAL_MODEL +
    CALIB_FIX_K3 + CALIB_FIX_K4 + CALIB_FIX_K5,
    TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, , ));
  cout << "done with RMS error=" << rms << endl;


  double err = ;
  int npoints = ;
  vector<Vec3f> lines[];
  for (int i = ; i < nimages; i++)
  {
    int npt = (int)imagePoints_l[i].size();
    Mat imgpt[];
    imgpt[] = Mat(imagePoints_l[i]);
    undistortPoints(imgpt[], imgpt[], cameraMatrix[], distCoeffs[], Mat(), cameraMatrix[]);
    computeCorrespondEpilines(imgpt[],  + , F, lines[]);

    imgpt[] = Mat(imagePoints_r[i]);
    undistortPoints(imgpt[], imgpt[], cameraMatrix[], distCoeffs[], Mat(), cameraMatrix[]);
    computeCorrespondEpilines(imgpt[],  + , F, lines[]);

    for (int j = ; j < npt; j++)
    {
      double errij = fabs(imagePoints[][i][j].x*lines[][j][] +
        imagePoints[][i][j].y*lines[][j][] + lines[][j][]) +
        fabs(imagePoints[][i][j].x*lines[][j][] +
        imagePoints[][i][j].y*lines[][j][] + lines[][j][]);
      err += errij;
    }
    npoints += npt;
  }
  cout << "average epipolar err = " << err / npoints << endl;

  FileStorage fs("intrinsics.yml", FileStorage::WRITE);
  if (fs.isOpened())
  {
    fs << "M1" << cameraMatrix[] << "D1" << distCoeffs[] <<
      "M2" << cameraMatrix[] << "D2" << distCoeffs[];
    fs.release();
  }
  else
    cout << "Error: can not save the intrinsic parameters\n";


  Mat R1, R2, P1, P2, Q;
  Rect validRoi[];

  stereoRectify(cameraMatrix[], distCoeffs[],
    cameraMatrix[], distCoeffs[],
    imageSize, R, T, R1, R2, P1, P2, Q,
    CALIB_ZERO_DISPARITY, , imageSize, &validRoi[], &validRoi[]);

  fs.open("extrinsics.yml", FileStorage::WRITE);
  if (fs.isOpened())
  {
    fs << "R" << R << "T" << T << "R1" << R1 << "R2" << R2 << "P1" << P1 << "P2" << P2 << "Q" << Q;
    fs.release();
  }
  else
    cout << "Error: can not save the extrinsic parameters\n";

  return ;
}           
  • 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
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 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
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218

注意标定的時候把各個方向,大小都照顧到。 

【OpenCV】基于OpenCV的雙目視覺測試 準備環境 雙目标定環節

到30之後就進入标定環節了。

立體比對

直接上完整代碼了。注意之前有人問我标定完之後如何去黑邊,可以注意一下裡面的函數

initUndistortRectifyMap(cameraMatrix[0], distCoeffs[0], R1, P1, imageSize, CV_16SC2, rmap[0][0], rmap[0][1]);           
  • 1
  • 1

這個就是用來計算校正後的映射的。後面可以計算出校正後的内接矩形,也就是校正後的無黑邊的圖像部分,會損失掉原圖像的邊緣。 

【OpenCV】基于OpenCV的雙目視覺測試 準備環境 雙目标定環節

此外,額,這次我自己測試的效果不是很好,之前在實驗室的時候要比寫文檔這次好很多,是以也希望你們可以把自己的結果發出來。看下圖的橫線的話,感覺還是标定的不太好。這次的文檔就當是一個流程介紹吧。 

【OpenCV】基于OpenCV的雙目視覺測試 準備環境 雙目标定環節
【OpenCV】基于OpenCV的雙目視覺測試 準備環境 雙目标定環節
#include <string>
#include <stdio.h>
#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace std;
using namespace cv;

vector<vector<Point2f> >corners_l_array, corners_r_array;
int array_index = ;
bool ChessboardStable(vector<Point2f>corners_l, vector<Point2f>corners_r){
  if (corners_l_array.size() < ){
    corners_l_array.push_back(corners_l);
    corners_r_array.push_back(corners_r);
    return false;
  }
  else{
    corners_l_array[array_index % ] = corners_l;
    corners_r_array[array_index % ] = corners_r;
    array_index++;
    double error = ;
    for (int i = ; i < corners_l_array.size(); i++){
      for (int j = ; j < corners_l_array[i].size(); j++){
        error += abs(corners_l[j].x - corners_l_array[i][j].x) + abs(corners_l[j].y - corners_l_array[i][j].y);
        error += abs(corners_r[j].x - corners_r_array[i][j].x) + abs(corners_r[j].y - corners_r_array[i][j].y);
      }
    }
    if (error < )
    {
      corners_l_array.clear();
      corners_r_array.clear();
      array_index = ;
      return true;
    }
    else
      return false;
  }
}


int main(){
  cv::VideoCapture camera_l();
  cv::VideoCapture camera_r();

  camera_l.set(CAP_PROP_FRAME_WIDTH, );
  camera_l.set(CAP_PROP_FRAME_HEIGHT, );
  camera_r.set(CAP_PROP_FRAME_WIDTH, );
  camera_r.set(CAP_PROP_FRAME_HEIGHT, );

  if (!camera_l.isOpened()){ cout << "No left camera!" << endl; return -; }
  if (!camera_r.isOpened()){ cout << "No right camera!" << endl; return -; }

  cv::Mat frame_l, frame_r;

  Size boardSize(, );
  const float squareSize = ;  // Set this to your actual square size

  vector<Mat> goodFrame_l;
  vector<Mat> goodFrame_r;

  vector<vector<Point2f> > imagePoints_l;
  vector<vector<Point2f> > imagePoints_r;

  vector<vector<Point3f> > objectPoints;

  int nimages = ;

  while (){
    camera_l >> frame_l;
    camera_r >> frame_r;

    bool found_l = false, found_r = false;

    vector<Point2f>corners_l, corners_r;
    found_l = findChessboardCorners(frame_l, boardSize, corners_l,
      CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_NORMALIZE_IMAGE);
    found_r = findChessboardCorners(frame_r, boardSize, corners_r,
      CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_NORMALIZE_IMAGE);


    if (found_l && found_r &&ChessboardStable(corners_l, corners_r)){
      goodFrame_l.push_back(frame_l);
      goodFrame_r.push_back(frame_r);

      Mat viewGray;
      cvtColor(frame_l, viewGray, COLOR_BGR2GRAY);
      cornerSubPix(viewGray, corners_l, Size(, ),
        Size(-, -), TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, , ));
      cvtColor(frame_r, viewGray, COLOR_BGR2GRAY);
      cornerSubPix(viewGray, corners_r, Size(, ),
        Size(-, -), TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, , ));

      imagePoints_l.push_back(corners_l);
      imagePoints_r.push_back(corners_r);
      ++nimages;
      frame_l += ;
      frame_r += ;

      drawChessboardCorners(frame_l, boardSize, corners_l, found_l);
      drawChessboardCorners(frame_r, boardSize, corners_r, found_r);

      putText(frame_l, to_string(nimages), Point(, ), , , Scalar(, , ));
      putText(frame_r, to_string(nimages), Point(, ), , , Scalar(, , ));
      imshow("Left Camera", frame_l);
      imshow("Right Camera", frame_r);
      char c = (char)waitKey();
      if (c ==  || c == 'q' || c == 'Q') //Allow ESC to quit
        exit(-);

      if (nimages >= )
        break;
    }
    else{
      drawChessboardCorners(frame_l, boardSize, corners_l, found_l);
      drawChessboardCorners(frame_r, boardSize, corners_r, found_r);

      putText(frame_l, to_string(nimages), Point(, ), , , Scalar(, , ));
      putText(frame_r, to_string(nimages), Point(, ), , , Scalar(, , ));
      imshow("Left Camera", frame_l);
      imshow("Right Camera", frame_r);

      char key = waitKey();
      if (key == )
        break;
    }


  }
  if (nimages < ){ cout << "Not enough" << endl; return -; }

  vector<vector<Point2f> > imagePoints[] = { imagePoints_l, imagePoints_r };

  objectPoints.resize(nimages);

  for (int i = ; i < nimages; i++)
  {
    for (int j = ; j < boardSize.height; j++)
    for (int k = ; k < boardSize.width; k++)
      objectPoints[i].push_back(Point3f(k*squareSize, j*squareSize, ));
  }

  cout << "Running stereo calibration ..." << endl;

  Size imageSize(, );

  Mat cameraMatrix[], distCoeffs[];
  cameraMatrix[] = initCameraMatrix2D(objectPoints, imagePoints_l, imageSize, );
  cameraMatrix[] = initCameraMatrix2D(objectPoints, imagePoints_r, imageSize, );
  Mat R, T, E, F;

  double rms = stereoCalibrate(objectPoints, imagePoints_l, imagePoints_r,
    cameraMatrix[], distCoeffs[],
    cameraMatrix[], distCoeffs[],
    imageSize, R, T, E, F,
    CALIB_FIX_ASPECT_RATIO +
    CALIB_ZERO_TANGENT_DIST +
    CALIB_USE_INTRINSIC_GUESS +
    CALIB_SAME_FOCAL_LENGTH +
    CALIB_RATIONAL_MODEL +
    CALIB_FIX_K3 + CALIB_FIX_K4 + CALIB_FIX_K5,
    TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, , ));
  cout << "done with RMS error=" << rms << endl;


  double err = ;
  int npoints = ;
  vector<Vec3f> lines[];
  for (int i = ; i < nimages; i++)
  {
    int npt = (int)imagePoints_l[i].size();
    Mat imgpt[];
    imgpt[] = Mat(imagePoints_l[i]);
    undistortPoints(imgpt[], imgpt[], cameraMatrix[], distCoeffs[], Mat(), cameraMatrix[]);
    computeCorrespondEpilines(imgpt[],  + , F, lines[]);

    imgpt[] = Mat(imagePoints_r[i]);
    undistortPoints(imgpt[], imgpt[], cameraMatrix[], distCoeffs[], Mat(), cameraMatrix[]);
    computeCorrespondEpilines(imgpt[],  + , F, lines[]);

    for (int j = ; j < npt; j++)
    {
      double errij = fabs(imagePoints[][i][j].x*lines[][j][] +
        imagePoints[][i][j].y*lines[][j][] + lines[][j][]) +
        fabs(imagePoints[][i][j].x*lines[][j][] +
        imagePoints[][i][j].y*lines[][j][] + lines[][j][]);
      err += errij;
    }
    npoints += npt;
  }
  cout << "average epipolar err = " << err / npoints << endl;

  FileStorage fs("intrinsics.yml", FileStorage::WRITE);
  if (fs.isOpened())
  {
    fs << "M1" << cameraMatrix[] << "D1" << distCoeffs[] <<
      "M2" << cameraMatrix[] << "D2" << distCoeffs[];
    fs.release();
  }
  else
    cout << "Error: can not save the intrinsic parameters\n";


  Mat R1, R2, P1, P2, Q;
  Rect validRoi[];

  stereoRectify(cameraMatrix[], distCoeffs[],
    cameraMatrix[], distCoeffs[],
    imageSize, R, T, R1, R2, P1, P2, Q,
    CALIB_ZERO_DISPARITY, , imageSize, &validRoi[], &validRoi[]);

  fs.open("extrinsics.yml", FileStorage::WRITE);
  if (fs.isOpened())
  {
    fs << "R" << R << "T" << T << "R1" << R1 << "R2" << R2 << "P1" << P1 << "P2" << P2 << "Q" << Q;
    fs.release();
  }
  else
    cout << "Error: can not save the extrinsic parameters\n";


  // OpenCV can handle left-right
  // or up-down camera arrangements
  bool isVerticalStereo = fabs(P2.at<double>(, )) > fabs(P2.at<double>(, ));

  // COMPUTE AND DISPLAY RECTIFICATION
  Mat rmap[][];
  // IF BY CALIBRATED (BOUGUET'S METHOD)

  //Precompute maps for cv::remap()
  initUndistortRectifyMap(cameraMatrix[], distCoeffs[], R1, P1, imageSize, CV_16SC2, rmap[][], rmap[][]);
  initUndistortRectifyMap(cameraMatrix[], distCoeffs[], R2, P2, imageSize, CV_16SC2, rmap[][], rmap[][]);

  Mat canvas;
  double sf;
  int w, h;
  if (!isVerticalStereo)
  {
    sf =  / MAX(imageSize.width, imageSize.height);
    w = cvRound(imageSize.width*sf);
    h = cvRound(imageSize.height*sf);
    canvas.create(h, w * , CV_8UC3);
  }
  else
  {
    sf =  / MAX(imageSize.width, imageSize.height);
    w = cvRound(imageSize.width*sf);
    h = cvRound(imageSize.height*sf);
    canvas.create(h * , w, CV_8UC3);
  }

  destroyAllWindows();

  Mat imgLeft, imgRight;

  int ndisparities =  * ;   /**< Range of disparity */
  int SADWindowSize = ; /**< Size of the block window. Must be odd */
  Ptr<StereoBM> sbm = StereoBM::create(ndisparities, SADWindowSize);
  sbm->setMinDisparity();
  //sbm->setNumDisparities(64);
  sbm->setTextureThreshold();
  sbm->setDisp12MaxDiff(-);
  sbm->setPreFilterCap();
  sbm->setUniquenessRatio();
  sbm->setSpeckleRange();
  sbm->setSpeckleWindowSize();


  Ptr<StereoSGBM> sgbm = StereoSGBM::create(, , ,
     *  * ,
     *  * ,
    , , , , , StereoSGBM::MODE_SGBM);


  Mat rimg, cimg;
  Mat Mask;
  while ()
  {
    camera_l >> frame_l;
    camera_r >> frame_r;

    if (frame_l.empty() || frame_r.empty())
      continue;

    remap(frame_l, rimg, rmap[][], rmap[][], INTER_LINEAR);
    rimg.copyTo(cimg);
    Mat canvasPart1 = !isVerticalStereo ? canvas(Rect(w * , , w, h)) : canvas(Rect(, h * , w, h));
    resize(cimg, canvasPart1, canvasPart1.size(), , , INTER_AREA);
    Rect vroi1(cvRound(validRoi[].x*sf), cvRound(validRoi[].y*sf),
      cvRound(validRoi[].width*sf), cvRound(validRoi[].height*sf));

    remap(frame_r, rimg, rmap[][], rmap[][], INTER_LINEAR);
    rimg.copyTo(cimg);
    Mat canvasPart2 = !isVerticalStereo ? canvas(Rect(w * , , w, h)) : canvas(Rect(, h * , w, h));
    resize(cimg, canvasPart2, canvasPart2.size(), , , INTER_AREA);
    Rect vroi2 = Rect(cvRound(validRoi[].x*sf), cvRound(validRoi[].y*sf),
      cvRound(validRoi[].width*sf), cvRound(validRoi[].height*sf));

    Rect vroi = vroi1&vroi2;

    imgLeft = canvasPart1(vroi).clone();
    imgRight = canvasPart2(vroi).clone();

    rectangle(canvasPart1, vroi1, Scalar(, , ), , );
    rectangle(canvasPart2, vroi2, Scalar(, , ), , );

    if (!isVerticalStereo)
    for (int j = ; j < canvas.rows; j += )
      line(canvas, Point(, j), Point(canvas.cols, j), Scalar(, , ), , );
    else
    for (int j = ; j < canvas.cols; j += )
      line(canvas, Point(j, ), Point(j, canvas.rows), Scalar(, , ), , );


    cvtColor(imgLeft, imgLeft, CV_BGR2GRAY);
    cvtColor(imgRight, imgRight, CV_BGR2GRAY);


    //-- And create the image in which we will save our disparities
    Mat imgDisparity16S = Mat(imgLeft.rows, imgLeft.cols, CV_16S);
    Mat imgDisparity8U = Mat(imgLeft.rows, imgLeft.cols, CV_8UC1);
    Mat sgbmDisp16S = Mat(imgLeft.rows, imgLeft.cols, CV_16S);
    Mat sgbmDisp8U = Mat(imgLeft.rows, imgLeft.cols, CV_8UC1);

    if (imgLeft.empty() || imgRight.empty())
    {
      std::cout << " --(!) Error reading images " << std::endl; return -;
    }

    sbm->compute(imgLeft, imgRight, imgDisparity16S);

    imgDisparity16S.convertTo(imgDisparity8U, CV_8UC1,  / );
    cv::compare(imgDisparity16S, , Mask, CMP_GE);
    applyColorMap(imgDisparity8U, imgDisparity8U, COLORMAP_HSV);
    Mat disparityShow;
    imgDisparity8U.copyTo(disparityShow, Mask);




    sgbm->compute(imgLeft, imgRight, sgbmDisp16S);

    sgbmDisp16S.convertTo(sgbmDisp8U, CV_8UC1,  / );
    cv::compare(sgbmDisp16S, , Mask, CMP_GE);
    applyColorMap(sgbmDisp8U, sgbmDisp8U, COLORMAP_HSV);
    Mat  sgbmDisparityShow;
    sgbmDisp8U.copyTo(sgbmDisparityShow, Mask);

    imshow("bmDisparity", disparityShow);
    imshow("sgbmDisparity", sgbmDisparityShow);
    imshow("rectified", canvas);
    char c = (char)waitKey();
    if (c ==  || c == 'q' || c == 'Q')
      break;
  }
  return ;
}           
  • 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
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 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
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360

此外你們可能還需要的代碼是讀取參數并進行雙目比對的代碼,我也在後面放出來了。 

額,因為不可能用一次标一次。

#include <string>
#include <stdio.h>
#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace std;
using namespace cv;



int main(){
  cv::VideoCapture camera_l(1);
  cv::VideoCapture camera_r(0);

  camera_l.set(CAP_PROP_FRAME_WIDTH, 320);
  camera_l.set(CAP_PROP_FRAME_HEIGHT, 240);
  camera_r.set(CAP_PROP_FRAME_WIDTH, 320);
  camera_r.set(CAP_PROP_FRAME_HEIGHT, 240);

  if (!camera_l.isOpened()){ cout << "No left camera!" << endl; return -1; }
  if (!camera_r.isOpened()){ cout << "No right camera!" << endl; return -1; }



  Mat cameraMatrix[2], distCoeffs[2];


  FileStorage fs("intrinsics.yml", FileStorage::READ);
  if (fs.isOpened())
  {
    fs["M1"] >> cameraMatrix[0];
    fs["D1"] >> distCoeffs[0];
    fs["M2"] >> cameraMatrix[1];
    fs["D2"] >> distCoeffs[1];
    fs.release();
  }
  else
    cout << "Error: can not save the intrinsic parameters\n";

  Mat R, T, E, F;
  Mat R1, R2, P1, P2, Q;
  Rect validRoi[2];
  Size imageSize(320, 240);

  fs.open("extrinsics.yml", FileStorage::READ);
  if (fs.isOpened())
  {
    fs["R"] >> R;
    fs["T"] >> T;
    fs["R1"] >> R1;
    fs["R2"] >> R2;
    fs["P1"] >> P1;
    fs["P2"] >> P2;
    fs["Q"] >> Q;
    fs.release();
  }
  else
    cout << "Error: can not save the extrinsic parameters\n";

  stereoRectify(cameraMatrix[0], distCoeffs[0],
    cameraMatrix[1], distCoeffs[1],
    imageSize, R, T, R1, R2, P1, P2, Q,
    CALIB_ZERO_DISPARITY, 1, imageSize, &validRoi[0], &validRoi[1]);

  // OpenCV can handle left-right
  // or up-down camera arrangements
  bool isVerticalStereo = fabs(P2.at<double>(1, 3)) > fabs(P2.at<double>(0, 3));

  // COMPUTE AND DISPLAY RECTIFICATION
  Mat rmap[2][2];
  // IF BY CALIBRATED (BOUGUET'S METHOD)

  //Precompute maps for cv::remap()
  initUndistortRectifyMap(cameraMatrix[0], distCoeffs[0], R1, P1, imageSize, CV_16SC2, rmap[0][0], rmap[0][1]);
  initUndistortRectifyMap(cameraMatrix[1], distCoeffs[1], R2, P2, imageSize, CV_16SC2, rmap[1][0], rmap[1][1]);

  Mat canvas;
  double sf;
  int w, h;
  if (!isVerticalStereo)
  {
    sf = 600. / MAX(imageSize.width, imageSize.height);
    w = cvRound(imageSize.width*sf);
    h = cvRound(imageSize.height*sf);
    canvas.create(h, w * 2, CV_8UC3);
  }
  else
  {
    sf = 300. / MAX(imageSize.width, imageSize.height);
    w = cvRound(imageSize.width*sf);
    h = cvRound(imageSize.height*sf);
    canvas.create(h * 2, w, CV_8UC3);
  }

  cv::Mat frame_l, frame_r;
  Mat imgLeft, imgRight;

  int ndisparities = 16 * 5;   /**< Range of disparity */
  int SADWindowSize = 31; /**< Size of the block window. Must be odd */
  Ptr<StereoBM> sbm = StereoBM::create(ndisparities, SADWindowSize);
  //    sbm->setMinDisparity(0);
  //    sbm->setNumDisparities(64);
  //    sbm->setTextureThreshold(10);
  //    sbm->setDisp12MaxDiff(-1);
  //    sbm->setPreFilterCap(31);
  //    sbm->setUniquenessRatio(25);
  //    sbm->setSpeckleRange(32);
  //    sbm->setSpeckleWindowSize(100);


  Ptr<StereoSGBM> sgbm = StereoSGBM::create(0, 64, 7,
    10 * 7 * 7,
    40 * 7 * 7,
    1, 63, 10, 100, 32, StereoSGBM::MODE_SGBM);


  Mat rimg, cimg;
  Mat Mask;
  while (1)
  {
    camera_l >> frame_l;
    camera_r >> frame_r;

    if (frame_l.empty() || frame_r.empty())
      continue;

    remap(frame_l, rimg, rmap[0][0], rmap[0][1], INTER_LINEAR);
    rimg.copyTo(cimg);
    Mat canvasPart1 = !isVerticalStereo ? canvas(Rect(w * 0, 0, w, h)) : canvas(Rect(0, h * 0, w, h));
    resize(cimg, canvasPart1, canvasPart1.size(), 0, 0, INTER_AREA);
    Rect vroi1(cvRound(validRoi[0].x*sf), cvRound(validRoi[0].y*sf),
      cvRound(validRoi[0].width*sf), cvRound(validRoi[0].height*sf));

    remap(frame_r, rimg, rmap[1][0], rmap[1][1], INTER_LINEAR);
    rimg.copyTo(cimg);
    Mat canvasPart2 = !isVerticalStereo ? canvas(Rect(w * 1, 0, w, h)) : canvas(Rect(0, h * 1, w, h));
    resize(cimg, canvasPart2, canvasPart2.size(), 0, 0, INTER_AREA);
    Rect vroi2 = Rect(cvRound(validRoi[1].x*sf), cvRound(validRoi[1].y*sf),
      cvRound(validRoi[1].width*sf), cvRound(validRoi[1].height*sf));

    Rect vroi = vroi1&vroi2;

    imgLeft = canvasPart1(vroi).clone();
    imgRight = canvasPart2(vroi).clone();

    rectangle(canvasPart1, vroi1, Scalar(0, 0, 255), 3, 8);
    rectangle(canvasPart2, vroi2, Scalar(0, 0, 255), 3, 8);

    if (!isVerticalStereo)
    for (int j = 0; j < canvas.rows; j += 32)
      line(canvas, Point(0, j), Point(canvas.cols, j), Scalar(0, 255, 0), 1, 8);
    else
    for (int j = 0; j < canvas.cols; j += 32)
      line(canvas, Point(j, 0), Point(j, canvas.rows), Scalar(0, 255, 0), 1, 8);


    cvtColor(imgLeft, imgLeft, CV_BGR2GRAY);
    cvtColor(imgRight, imgRight, CV_BGR2GRAY);


    //-- And create the image in which we will save our disparities
    Mat imgDisparity16S = Mat(imgLeft.rows, imgLeft.cols, CV_16S);
    Mat imgDisparity8U = Mat(imgLeft.rows, imgLeft.cols, CV_8UC1);
    Mat sgbmDisp16S = Mat(imgLeft.rows, imgLeft.cols, CV_16S);
    Mat sgbmDisp8U = Mat(imgLeft.rows, imgLeft.cols, CV_8UC1);

    if (imgLeft.empty() || imgRight.empty())
    {
      std::cout << " --(!) Error reading images " << std::endl; return -1;
    }

    sbm->compute(imgLeft, imgRight, imgDisparity16S);

    imgDisparity16S.convertTo(imgDisparity8U, CV_8UC1, 255.0 / 1000.0);
    cv::compare(imgDisparity16S, 0, Mask, CMP_GE);
    applyColorMap(imgDisparity8U, imgDisparity8U, COLORMAP_HSV);
    Mat disparityShow;
    imgDisparity8U.copyTo(disparityShow, Mask);




    sgbm->compute(imgLeft, imgRight, sgbmDisp16S);

    sgbmDisp16S.convertTo(sgbmDisp8U, CV_8UC1, 255.0 / 1000.0);
    cv::compare(sgbmDisp16S, 0, Mask, CMP_GE);
    applyColorMap(sgbmDisp8U, sgbmDisp8U, COLORMAP_HSV);
    Mat  sgbmDisparityShow;
    sgbmDisp8U.copyTo(sgbmDisparityShow, Mask);

    imshow("bmDisparity", disparityShow);
    imshow("sgbmDisparity", sgbmDisparityShow);
    imshow("rectified", canvas);
    char c = (char)waitKey(1);
    if (c == 27 || c == 'q' || c == 'Q')
      break;
  }
  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
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 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
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205

謝謝你能有耐心看完這篇文檔

繼續閱讀