双目视觉的例子(Stereo算法)

来源:互联网 发布:淘宝信誉升级规则 编辑:程序博客网 时间:2024/04/28 01:18

刚才整理了下我以前做过的Stereo算法, 给大家分享下. 在Windows VS2008, 和MacOS下用Xcode, openCV做的.
源码在下边, 如果要直接用的话, 图像路径要改改.

Left tsukuba image: http://graphics.cis.udel.edu/research/C ... reo1/L.jpg
right tsukuba image: http://graphics.cis.udel.edu/research/C ... reo1/R.jpg

大约4,5秒钟 window size=11, disparity search range=20
matching 的算法是Normal Cross Correlation...


(VS2008+OpenCV 1.1)

// cvStereoNCC.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <math.h>
#include <ctime>


using namespace std;
template<class T> class Image
{
   private: 
      IplImage* imgp;
   public:
      Image(IplImage* img=0){imgp=img;}
      ~Image(){imgp=0;}
      void operator=(IplImage* img){imgp=img;}
      inline T* operator[](const int rowIndx){
         return((T*)(imgp->imageData+rowIndx*imgp->widthStep));}

};

typedef struct{
   unsigned char b,g,r;
}RgbPixel;

typedef struct{
   float b,g,r;
}RgbPixelFloat;

typedef Image<RgbPixel> RgbImage;
typedef Image<RgbPixelFloat> RgbImageFloat;
typedef Image<unsigned char> BwImage;
typedef Image<float> BwImageFloat;





/*
coded and updated by Huang, Haiqiao 2010-01-07
Normalized Cross Correlation Strereo Vision algorithm
*/

void displayImageProperty(IplImage* image){ 
   cout<<"-------Image Properties--------"<<endl;
   cout<<"Image width="<<image->width<<endl;
   cout<<"Image height="<<image->height<<endl;
   cout<<"Image depth="<<image->depth<<endl;
   cout<<"Image nSize="<<image->nSize<<endl;
   cout<<"Image nChannels="<<image->nChannels<<endl; 
   char* origin;
   char* dataOrder;
   if (image->origin==0){
       origin="Top-left";
   }else{
       origin="Below-left";//image->origin=1
   }
   cout<<"Image origin="<<origin<<endl;

   if (image->dataOrder==0){
       dataOrder="Order_Pixel(Interleaved)";
   }else{
       dataOrder="Order_Plane";//image->dataOrder=1
   }
   cout<<"Image dataOrder="<<dataOrder<<endl;
   cout<<"Image widthStep="<<image->widthStep<<" Bytes"<<endl;


}

//display an image in a new window with title to be given.
void displayImageNewWindow(char* title,CvArr* img){
   cvNamedWindow(title, CV_WINDOW_AUTOSIZE );
   cvShowImage(title,img); 
}


int getMaxMin(double value[],int valueSize, int maxmin)
{
   int pos=0;
   int i=0;
   double max1=-1;//?-999999;
   double min1=999999;
   
   if (maxmin==1){//find max
      for (i=0;i<valueSize;i++){//find the index with the max ncc; 
         if (value[i]>max1){
            pos=i;
            max1=value[i];
         }
      }
   }
   
   if (maxmin==0){//find min
      for (i=0;i<valueSize;i++){//find the index with the max ncc; 
         if (value[i]<min1){
            pos=i;
            min1=value[i];
         }
      }          
   }
      
   return pos;
}




IplImage* generateDisparityImage(IplImage* greyLeftImg32,
                         IplImage* greyRightImg32, 
                         int windowSize,int DSR){

    int offset=floor((double)windowSize/2); 
   int height=greyLeftImg32->height;
   int width=greyLeftImg32->width;
    double* localNCC=new double[DSR];

   int x=0, y=0,d=0,m=0;
   int N=windowSize;             

   IplImage* leftWinImg=cvCreateImage(cvSize(N,N),32,1);//mySubImage(greyLeftImg32,cvRect(0,0,N,N));
   IplImage* rightWinImg=cvCreateImage(cvSize(N,N),32,1);;//mySubImage(greyRightImg32,cvRect(0,0,N,N));
   IplImage* disparity=cvCreateImage(cvSize(width,height),8,1);//or IPL_DEPTH_8U
   BwImage imgA(disparity);
   
   for (y=0;y<height;y++){ 
      for (x=0;x<width;x++){
         imgA[y][x]=0;
      }
   }
   
     CvScalar s1;
   CvScalar s2;
   for (y=0;y<height-N;y++){ //height-N
      for (x=0;x<width-N;x++){//width-N
         //getWindow(i,j,leftim,wl,N);
         cvSetImageROI(greyLeftImg32, cvRect(x,y,N,N));
         s1=cvAvg(greyLeftImg32,NULL);
         cvSubS(greyLeftImg32,s1,leftWinImg,NULL);//zero-means
         cvNormalize(leftWinImg,leftWinImg,0,0,CV_L2,NULL);
         d=0;
         
          //initialise localNCC
          for (m=0;m<DSR;m++){localNCC[m]=0;}
          
          do{ 
            if (x-d>=0){
    
               cvSetImageROI(greyRightImg32, cvRect(x-d,y,N,N));
               s2=cvAvg(greyRightImg32,NULL);
               cvSubS(greyRightImg32,s2,rightWinImg,NULL);//zero-means 
               cvNormalize(rightWinImg,rightWinImg,0,0,CV_L2,NULL); 
            }else{
               break;
            }  
            localNCC[d]=cvDotProduct(leftWinImg,rightWinImg); 
            cvResetImageROI(greyRightImg32); 
            d++;
         }while(d<=DSR);
         
         //to find the best d and store
          imgA[y+offset][x+offset]=getMaxMin(localNCC,DSR,1)*16; 
         cvResetImageROI(greyLeftImg32);
      }//x 
      if (y%10==0)cout<<"row="<<y<<" of "<<height<<endl;  
   }//y
   
   cvReleaseImage(&leftWinImg); 
   cvReleaseImage(&rightWinImg); 
        
   return disparity;

}





int main (int argc, char * const argv[]) {
    // insert code here...
    cout << "Stereo Normalized Cross Correlation"<<endl;  
    
   //**********image input*********************//
    

   char* filename1="D:/OpenCV_stuff/SampleImages/im2_tsu.bmp";//im2_cone.png
   IplImage* greyLeftImg= cvLoadImage(filename1,0);
   char* filename2="D:/OpenCV_stuff/SampleImages/im6_tsu.bmp";
   IplImage* greyRightImg= cvLoadImage(filename2,0); 
   
   if (greyLeftImg==NULL){
      cout << "No valid image input."<<endl; 
      //char c=getchar();
      return 1;
   }else{displayImageProperty(greyLeftImg);}
   if (greyRightImg==NULL){
      cout << "No valid image input."<<endl; 
      //char c=getchar();
      return 1;
   }

   int width=greyLeftImg->width;
   int height=greyLeftImg->height;  

   /****************8U to 32F**********************/
   IplImage* greyLeftImg32=cvCreateImage(cvSize(width,height),32,1);//IPL_DEPTH_32F 
   IplImage* greyRightImg32=cvCreateImage(cvSize(width,height),32,1); 
   cvConvertScale(greyLeftImg, greyLeftImg32, 1/255.);
   cvConvertScale(greyRightImg, greyRightImg32, 1/255.);//1/255. equals to 1/255.0 
    
   //-------------Computing stereo matching---------------- 
   time_t tstart, tend; 
   tstart = time(0); 
   int windowSize=11,DSR=20;//Disparity Search Range
   IplImage* disparity32=generateDisparityImage(greyLeftImg32,greyRightImg32,windowSize,DSR); 
   tend = time(0);
   cout << "It took "<< difftime(tend, tstart) <<" second(s)."<< endl;

   displayImageNewWindow("Dispairty Image",disparity32);
   displayImageNewWindow("Left Image",greyLeftImg32);
   displayImageNewWindow("Right Image",greyRightImg32);
    //cvSaveImage("D:/OpenCV_stuff/SampleImages/disparity.jpg",disparity32);

   //********destroy window************/
   cvWaitKey(0);
   cvReleaseImage(&greyLeftImg32);
   cvReleaseImage(&greyRightImg32);
   cvReleaseImage(&greyLeftImg);
   cvReleaseImage(&greyRightImg); 
   cvReleaseImage(&disparity32); 
   cvDestroyWindow("Left Image"); 
   cvDestroyWindow("Right Image"); 
   cvDestroyWindow("Dispairty Image"); 
    return 0;

}

(Mac OS, Xcode)

/*************
Huang, Haiqiao 2009-10-29
*************/

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <math.h>
#include <ctime>


using namespace std;

template<class T> class Image
{
   private: 
      IplImage* imgp;
   public:
      Image(IplImage* img=0){imgp=img;}
      ~Image(){imgp=0;}
      void operator=(IplImage* img){imgp=img;}
      inline T* operator[](const int rowIndx){
         return((T*)(imgp->imageData+rowIndx*imgp->widthStep));}

};
typedef struct{
   unsigned char b,g,r;
}RgbPixel;

typedef struct{
   float b,g,r;
}RgbPixelFloat;

typedef Image<RgbPixel> RgbImage;
typedef Image<RgbPixelFloat> RgbImageFloat;
typedef Image<unsigned char> BwImage;
typedef Image<float> BwImageFloat;
  


void displayImageProperty(IplImage* image){ 
   cout<<"-------Image Properties--------"<<endl;
   cout<<"Image width="<<image->width<<endl;
   cout<<"Image height="<<image->height<<endl;
   cout<<"Image depth="<<image->depth<<endl;
   cout<<"Image nSize="<<image->nSize<<endl;
   cout<<"Image nChannels="<<image->nChannels<<endl; 
   char* origin;
   char* dataOrder;
   if (image->origin==0){
       origin="Top-left";
   }else{
       origin="Below-left";//image->origin=1
   }
   cout<<"Image origin="<<origin<<endl;

   if (image->dataOrder==0){
       dataOrder="Order_Pixel(Interleaved)";
   }else{
       dataOrder="Order_Plane";//image->dataOrder=1
   }
   cout<<"Image dataOrder="<<dataOrder<<endl;
   cout<<"Image widthStep="<<image->widthStep<<" Bytes"<<endl;


}

//display an image in a new window with title to be given.
void displayImageNewWindow(char* title,CvArr* img){
   cvNamedWindow(title, CV_WINDOW_AUTOSIZE);
   cvShowImage(title,img); 
}

int getMaxMin(double value[],int valueSize, int maxmin)
{
   int pos=0;
   int i=0;
   double max1=-1;//å-999999;
   double min1=999999;
   
   if (maxmin==1){//find max
      for (i=0;i<valueSize;i++){//find the index with the max ncc; 
         if (value[i]>max1){
            pos=i;
            max1=value[i];
         }
      }
   }
   
   if (maxmin==0){//find min
      for (i=0;i<valueSize;i++){//find the index with the max ncc; 
         if (value[i]<min1){
            pos=i;
            min1=value[i];
         }
      }          
   }
      
   return pos;
}



IplImage* generateDisparityImage(IplImage* greyLeftImg32,
                         IplImage* greyRightImg32, 
                         int windowSize,int DSR){

    int offset=floor((double)windowSize/2); 
   int height=greyLeftImg32->height;
   int width=greyLeftImg32->width;
    double* localNCC=new double[DSR];

   int x=0, y=0,d=0,m=0;
   int N=windowSize;             

   IplImage* leftWinImg=cvCreateImage(cvSize(N,N),32,1);//mySubImage(greyLeftImg32,cvRect(0,0,N,N));
   IplImage* rightWinImg=cvCreateImage(cvSize(N,N),32,1);;//mySubImage(greyRightImg32,cvRect(0,0,N,N));
   IplImage* disparity=cvCreateImage(cvSize(width,height),8,1);//or IPL_DEPTH_8U
   BwImage imgA(disparity);
   
   for (y=0;y<height;y++){ 
      for (x=0;x<width;x++){
         imgA[y][x]=0;
      }
   }
   
     CvScalar s1;
   CvScalar s2;
   for (y=0;y<height-N;y++){ //height-N
      for (x=0;x<width-N;x++){//width-N
         //getWindow(i,j,leftim,wl,N);
         cvSetImageROI(greyLeftImg32, cvRect(x,y,N,N));
         s1=cvAvg(greyLeftImg32,NULL);
         cvSubS(greyLeftImg32,s1,leftWinImg,NULL);//zero-means
         cvNormalize(leftWinImg,leftWinImg,0,0,CV_L2,NULL);
         d=0;
         
          //initialise localNCC
          for (m=0;m<DSR;m++){localNCC[m]=0;}
          
          do{ 
            if (x-d>=0){ 
               cvSetImageROI(greyRightImg32, cvRect(x-d,y,N,N));
               s2=cvAvg(greyRightImg32,NULL);
               cvSubS(greyRightImg32,s2,rightWinImg,NULL);//zero-means 
               cvNormalize(rightWinImg,rightWinImg,0,0,CV_L2,NULL);
               
            }else{
               break;
            } 
            //localNCC[d]=NCC_val(leftWinImg,rightWinImg);
            localNCC[d]=cvDotProduct(leftWinImg,rightWinImg); 
            cvResetImageROI(greyRightImg32);

            d++;
         }while(d<=DSR);
         
         //to find the best d and store
          imgA[y+offset][x+offset]=getMaxMin(localNCC,DSR,1)*16; 
         cvResetImageROI(greyLeftImg32);
      }//x 
      if (y%10==0)cout<<"row="<<y<<endl;  
   }//y
   
   cvReleaseImage(&leftWinImg); 
   cvReleaseImage(&rightWinImg); 
        
   return disparity;

}



int main (int argc, char * const argv[]) {
    // insert code here...
    cout << "Stereo Normalized Cross Correlation"<<endl;  
   

   //**********image input*********************//
   //left_rds1.bmp,
   char* filename1="/Users/haiqiaohuang/Desktop/ProjectsOfEclipse/CppOpenCV/SampleImages/im2_tsu.bmp";//im2_cone.png
   IplImage* greyLeftImg= cvLoadImage(filename1,0); //0 means load image as grey image
   char* filename2="/Users/haiqiaohuang/Desktop/ProjectsOfEclipse/CppOpenCV/SampleImages/im6_tsu.bmp";
   IplImage* greyRightImg= cvLoadImage(filename2,0); 
   
    //----------image validity testing------------------ 
   if (greyLeftImg==NULL){
      cout << "No valid image input."<<endl; 
      //char c=getchar();
      return 1;
   }else{displayImageProperty(greyLeftImg);}
   if (greyRightImg==NULL){
      cout << "No valid image input."<<endl; 
      //char c=getchar();
      return 1;
   }

   int width=greyLeftImg->width;
   int height=greyLeftImg->height; 

   /****************8U to 32F**********************/
   IplImage* greyLeftImg32=cvCreateImage(cvSize(width,height),32,1);//IPL_DEPTH_32F 
   IplImage* greyRightImg32=cvCreateImage(cvSize(width,height),32,1); 
   cvConvertScale(greyLeftImg, greyLeftImg32, 1/255.);
   cvConvertScale(greyRightImg, greyRightImg32, 1/255.);//1/255. equals to 1/255.0 
    
   //-------------Computing disparity image---------------- 
   time_t tstart, tend; 
   tstart = time(0); //start timing
   int windowSize=13;//window size
   int DSR=20;//Disparity Search Range;
   IplImage* disparity32=generateDisparityImage(greyLeftImg32,greyRightImg32,windowSize,DSR); 
   tend = time(0);//end timing
   cout << "It took "<< difftime(tend, tstart) <<" second(s)."<< endl;


   //--------------display stereo results----------------------
   displayImageNewWindow("Dispairty Image",disparity32);
   displayImageNewWindow("Left Image",greyLeftImg32);
   displayImageNewWindow("Right Image",greyRightImg32);


   //********destroy window************/
   cvWaitKey(0);
   cvReleaseImage(&greyLeftImg32);
   cvReleaseImage(&greyRightImg32);
   cvReleaseImage(&greyLeftImg);
   cvReleaseImage(&greyRightImg); 
   cvReleaseImage(&disparity32);
   
   
   cvDestroyWindow("Left Image"); 
   cvDestroyWindow("Right Image"); 
   cvDestroyWindow("Dispairty Image");
        
    return 0;
}


原创粉丝点击