SAD立体匹配算法在opencv中的实现

时间:2022-10-04 05:55:46

FROM:http://blog.csdn.net/tulun/article/details/6456188

SAD算法具体原理见相关图像处理书籍。

该程序是opencv中文论坛的牛人贡献的,感谢他的工作。

 

(程序所需图片可以在网上找如http://vision.middlebury.edu/stereo/data/scenes2003/

[c-sharp] view plaincopyprint?
  1. // Sum of Absolute Difference(SAD)   
  2.  
  3. #include <iostream>  
  4. #include <stdio.h>  
  5. #include <stdlib.h>  
  6. #include <cv.h>  
  7. #include <cxcore.h>  
  8. #include <highgui.h>  
  9. #include <math.h>  
  10. #include <ctime>  
  11.   
  12. using namespace std;  
  13.   
  14. template<class T> class Image  
  15. {  
  16. private:  
  17.     IplImage* imgp;  
  18.   
  19. public:  
  20.     Image(IplImage* img=0){imgp=img;}  
  21.     ~Image(){imgp=0;}  
  22.     void operator=(IplImage* img){imgp=img;}  
  23.     inline T* operator[](const int rowIndx)  
  24.     {  
  25.         return((T*)(imgp->imageData+rowIndx*imgp->widthStep));  
  26.     }  
  27. };  
  28.   
  29. typedef struct  
  30. {  
  31.     unsigned char b,g,r;  
  32. }RgbPixel;  
  33.   
  34. typedef struct  
  35. {  
  36.     float b,g,r;  
  37. }RgbPixelFloat;  
  38.   
  39. typedef Image<RgbPixel> RgbImage;  
  40. typedef Image<RgbPixelFloat> RgbImageFloat;  
  41. typedef Image<unsigned char> BwImage;  
  42. typedef Image<float> BwImageFloat;  
  43.   
  44. //display an image in a new window with title to be given.  
  45. void displayImageNewWindow(char* title,CvArr* img)  
  46. {  
  47.     cvNamedWindow(title, CV_WINDOW_AUTOSIZE );  
  48.     cvShowImage(title,img);  
  49. }  
  50.   
  51. int getMaxMin(double value[],int valueSize, int maxmin)  
  52. {  
  53.     int pos=0;  
  54.     int i=0;  
  55.     double max1=-1;//?-999999;  
  56.     double min1=999999;  
  57.          
  58.     if (maxmin==1)  
  59.     {  
  60.         //find max  
  61.         for (i=0;i<valueSize;i++)  
  62.         {  
  63.             //find the index with the max value;  
  64.             if (value[i]>max1)  
  65.             {  
  66.                 pos=i;  
  67.                 max1=value[i];  
  68.             }  
  69.         }  
  70.     }  
  71.          
  72.     if (maxmin==0)  
  73.     {  
  74.         //find min  
  75.         for (i=0;i<valueSize;i++)  
  76.         {  
  77.             //find the index with the minimum value;  
  78.             if (value[i]<min1)  
  79.             {  
  80.                 pos=i;  
  81.                 min1=value[i];  
  82.             }  
  83.         }           
  84.     }  
  85.             
  86.     return pos;  
  87. }  
  88.   
  89. IplImage* generateDisparityImage(IplImage* greyLeftImg32,IplImage* greyRightImg32,int windowSize,int DSR)  
  90. {  
  91.     int offset=floor((double)windowSize/2);  
  92.     int height=greyLeftImg32->height;  
  93.     int width=greyLeftImg32->width;  
  94.     double* localSAD=new double[DSR];  
  95.   
  96.     int x=0, y=0,d=0,m=0;  
  97.     int N=windowSize;              
  98.   
  99.     IplImage* winImg=cvCreateImage(cvSize(N,N),32,1);//mySubImage(greyLeftImg32,cvRect(0,0,N,N));  
  100.      
  101.     IplImage* disparity=cvCreateImage(cvSize(width,height),8,1);//or IPL_DEPTH_8U  
  102.     BwImage imgA(disparity);  
  103.      
  104.     for (y=0;y<height;y++)  
  105.     {  
  106.       for (x=0;x<width;x++)  
  107.       {  
  108.          imgA[y][x]=0;  
  109.       }  
  110.     }  
  111.          
  112.     CvScalar sum;  
  113.     //CvScalar s2;  
  114.     for (y=0;y<height-N;y++)  
  115.     {   
  116.         //height-N  
  117.         for (x=0;x<width-N;x++)  
  118.         {  
  119.             //width-N  
  120.             cvSetImageROI(greyLeftImg32, cvRect(x,y,N,N));  
  121.             d=0;           
  122.             //initialise localSAD  
  123.             for (m=0;m<DSR;m++)  
  124.             {  
  125.                 localSAD[m]=0;  
  126.             }  
  127.        
  128.             //start matching  
  129.              do{  
  130.                 if (x-d>=0)  
  131.                 {  
  132.                     cvSetImageROI(greyRightImg32, cvRect(x-d,y,N,N));  
  133.                 }  
  134.                 else  
  135.                 {  
  136.                 break;  
  137.                 }  
  138.   
  139.                 cvAbsDiff(greyLeftImg32,greyRightImg32,winImg);//absolute difference  
  140.                 sum=cvSum(winImg);//sum  
  141.                 localSAD[d]=sum.val[0];//0 means single channel  
  142.   
  143.                 cvResetImageROI(greyRightImg32);  
  144.                 d++;  
  145.             }while(d<=DSR);  
  146.        
  147.             //to find the best d and store  
  148.             imgA[y+offset][x+offset]=getMaxMin(localSAD,DSR,0)*16; //0 means return minimum index  
  149.             cvResetImageROI(greyLeftImg32);  
  150.         }//x  
  151.         if (y%10==0)  
  152.             cout<<"row="<<y<<" of "<<height<<endl;   
  153.     }//y  
  154.   
  155.     cvReleaseImage(&winImg);  
  156.     //cvReleaseImage(&rightWinImg);  
  157.      
  158.     return disparity;  
  159. }  
  160.   
  161. int main (int argc, char * const argv[])   
  162. {  
  163.     cout << "Sum of Absolute Difference(SAD) Strereo Vision"<<endl;   
  164.          
  165.     //**********image input*********************//   
  166.     char* filename1="L.jpg";//im2_cone.png  
  167.     IplImage* greyLeftImg= cvLoadImage(filename1,0);  
  168.     char* filename2="R.jpg";  
  169.     IplImage* greyRightImg= cvLoadImage(filename2,0);  
  170.          
  171.     if (greyLeftImg==NULL){cout << "No valid image input."<<endl; return 1;}  
  172.     if (greyRightImg==NULL){cout << "No valid image input."<<endl; return 1;}  
  173.   
  174.     int width=greyLeftImg->width;  
  175.     int height=greyLeftImg->height;   
  176.   
  177.     /****************8U to 32F**********************/  
  178.     IplImage* greyLeftImg32=cvCreateImage(cvSize(width,height),32,1);//IPL_DEPTH_32F  
  179.     IplImage* greyRightImg32=cvCreateImage(cvSize(width,height),32,1);  
  180.     cvConvertScale(greyLeftImg, greyLeftImg32, 1/255.);  
  181.     cvConvertScale(greyRightImg, greyRightImg32, 1/255.);//1/255. equals to 1/255.0  
  182.          
  183.     //-------------obtain disparity image----------------  
  184.     time_t tstart, tend;  
  185.     tstart = time(0);  
  186.     int windowSize=13,DSR=20;//Disparity Search Range  
  187.     IplImage* disparity32=generateDisparityImage(greyLeftImg32,greyRightImg32,windowSize,DSR);  
  188.     tend = time(0);  
  189.     cout << "It took "<< difftime(tend, tstart) <<" second(s)."<< endl;  
  190.   
  191.     displayImageNewWindow("Dispairty Image",disparity32);  
  192.     displayImageNewWindow("Left Image",greyLeftImg32);  
  193.     displayImageNewWindow("Right Image",greyRightImg32);  
  194.          
  195.     //cvSaveImage("D:/OpenCV_stuff/SampleImages/disparitySAD.jpg",disparity32);  
  196.   
  197.     //********destroy window************/  
  198.     cvWaitKey(0);  
  199.     cvReleaseImage(&greyLeftImg32);  
  200.     cvReleaseImage(&greyRightImg32);  
  201.     cvReleaseImage(&greyLeftImg);  
  202.     cvReleaseImage(&greyRightImg);  
  203.     cvReleaseImage(&disparity32);  
  204.     cvDestroyWindow("Left Image");  
  205.     cvDestroyWindow("Right Image");  
  206.     cvDestroyWindow("Dispairty Image");  
  207.     return 0;