立体匹配算法
轉載請注明出處:http://www.cnblogs.com/adong7639/p/4267326.html
立體匹配算法最新動態:
http://vision.middlebury.edu/stereo/eval/
http://www.cvlibs.net/datasets/kitti/eval_stereo_flow.php?benchmark=stereo
相關文獻:http://blog.csdn.net/xuyuhua1985/article/details/26283389
介紹立體匹配的基本原理:?http://vision.deis.unibo.it/~smatt/Seminars/StereoVision.pdf(比較清晰)
立體匹配綜述性文章 :?http://wenku.baidu.com/view/5b359d7d5acfa1c7aa00cc7b.html
立體匹配算法的基本目標:找出圖像的每個像素點在另一個視角的圖像上對應的像素點,算出視差圖像,估算出景深圖像。
最簡單的SAD塊匹配算法
//Stereo Match By SAD #include <opencv2/opencv.hpp> #include <vector> #include <algorithm> #include <iostream> #include <windows.h> #include <string> using namespace std; using namespace cv;DWORD t1; DWORD t2; void timebegin() { t1 = GetTickCount(); } void timeend(string str) { t2 = GetTickCount(); cout << str << " is "<< (t2 - t1)/1000 << "s" << endl; } float sadvalue(const Mat &src1, const Mat &src2) {Mat matdiff = cv::abs(src1 -src2);int saddiff = cv::sum(matdiff)[0];return saddiff; }float GetMinSadIndex(std::vector<float> &sad) {float minsad = sad[0];int index = 0;int len = sad.size();for (int i = 1; i < len; ++i){if (sad[i] < minsad){minsad = sad[i];index = i;}}return index; }void MatDataNormal(const Mat &src, Mat &dst) {normalize(src, dst, 255, 0, NORM_MINMAX );dst.convertTo(dst, CV_8UC1); }void GetPointDepthRight(Mat &disparity, const Mat &leftimg, const Mat &rightimg, const int MaxDisparity, const int winsize) {int row = leftimg.rows;int col = leftimg.cols;if (leftimg.channels() == 3 && rightimg.channels() == 3){cvtColor(leftimg, leftimg, CV_BGR2GRAY);cvtColor(rightimg, rightimg, CV_BGR2GRAY);}//Mat disparity = Mat ::zeros(row,col, CV_32S);int w = winsize;int rowrange = row - w;int colrange = col - w - MaxDisparity;for (int i = w; i < rowrange; ++i){int *ptr = disparity.ptr<int>(i);for (int j = w; j < colrange; ++j){//Rect rightrect;Mat rightwin = rightimg(Range(i - w,i + w + 1),Range(j - w,j + w + 1)); std::vector<float> sad(MaxDisparity);for (int d = j; d < j + MaxDisparity; ++d){//Rect leftrect;Mat leftwin = leftimg(Range(i - w,i + w + 1),Range(d - w,d + w + 1));sad[d - j] = sadvalue(leftwin, rightwin);}*(ptr + j) = GetMinSadIndex(sad);}} }void GetPointDepthLeft(Mat &disparity, const Mat &leftimg, const Mat &rightimg, const int MaxDisparity, const int winsize) {int row = leftimg.rows;int col = leftimg.cols;if (leftimg.channels() == 3 && rightimg.channels() == 3){cvtColor(leftimg, leftimg, CV_BGR2GRAY);cvtColor(rightimg, rightimg, CV_BGR2GRAY);}//Mat disparity = Mat ::zeros(row,col, CV_32S);int w = winsize;int rowrange = row - w;int colrange = col - w;for (int i = w; i < rowrange; ++i){int *ptr = disparity.ptr<int>(i);for (int j = MaxDisparity + w; j < colrange; ++j){//Rect leftrect;Mat leftwin = leftimg(Range(i - w,i + w + 1),Range(j - w,j + w + 1)); std::vector<float> sad(MaxDisparity);for (int d = j; d > j - MaxDisparity; --d){//Rect rightrect;Mat rightwin = rightimg(Range(i - w,i + w + 1),Range(d - w,d + w + 1));sad[j - d] = sadvalue(leftwin, rightwin);}*(ptr + j) = GetMinSadIndex(sad);}} }//(Left-Right Consistency (LRC) void CrossCheckDiaparity(const Mat &leftdisp, const Mat &rightdisp, Mat &lastdisp, const int MaxDisparity, const int winsize) {int row = leftdisp.rows;int col = rightdisp.cols;int w = winsize;int rowrange = row - w;int colrange = col - MaxDisparity - w;int diffthreshold = 2;for (int i = w; i < row -w; ++i){const int *ptrleft = leftdisp.ptr<int>(i);const int *ptrright = rightdisp.ptr<int>(i);int *ptrdisp = lastdisp.ptr<int>(i);for (int j = MaxDisparity + w; j < col - MaxDisparity - w; ++j){int leftvalue = *(ptrleft + j);int rightvalue = *(ptrright + j - leftvalue );int diff = abs(leftvalue - rightvalue);if (diff > diffthreshold){*(ptrdisp + j) = 0;}else{*(ptrdisp + j) = leftvalue;}}}}int main() {Mat leftimg = imread("left1.png",0); Mat rightimg = imread("right1.png",0); if (leftimg.channels() == 3 && rightimg.channels() == 3){cvtColor(leftimg, leftimg, CV_BGR2GRAY);cvtColor(rightimg, rightimg, CV_BGR2GRAY);}float scale = 1;int row = leftimg.rows * scale;int col = leftimg.cols * scale;resize(leftimg, leftimg, Size( col, row));resize(rightimg,rightimg, Size(col, row));Mat depthleft = Mat ::zeros(row,col, CV_32S);Mat depthright = Mat ::zeros(row,col, CV_32S);Mat lastdisp = Mat ::zeros(row,col, CV_32S);int MaxDisparity = 60 * scale;int winsize = 31*scale;timebegin();GetPointDepthLeft(depthleft, leftimg, rightimg, MaxDisparity, winsize);GetPointDepthRight(depthright, leftimg, rightimg, MaxDisparity, winsize);CrossCheckDiaparity(depthleft,depthright, lastdisp, MaxDisparity, winsize);timeend("time ");MatDataNormal(depthleft,depthleft);MatDataNormal(depthright, depthright);MatDataNormal(lastdisp, lastdisp);namedWindow("left", 0);namedWindow("right", 0);namedWindow("depthleft", 0);namedWindow("depthright", 0);namedWindow("lastdisp",0);imshow("left", leftimg);imshow("right", rightimg);imshow("depthleft", depthleft);imshow("depthright", depthright);imshow("lastdisp",lastdisp);string strsave = "result_";imwrite(strsave +"depthleft.jpg", depthleft);imwrite(strsave +"depthright.jpg", depthright);imwrite(strsave +"lastdisp.jpg",lastdisp);waitKey(0);return 0; }
總結
- 上一篇: face key point with
- 下一篇: OpenCv中实现了三种立体匹配算法: