1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 立体匹配之NCC算法

立体匹配之NCC算法

时间:2020-12-04 00:32:14

相关推荐

立体匹配之NCC算法

FROM:/tulun/article/details/6388759

NCC算法(Normal Cross Correlation),具体原理见相关图像处理书籍。

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

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

#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,1,0,CV_L2,NULL);//0变成1

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,1,0,CV_L2,NULL);//0变成1

}

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="im0.ppm";//im2_cone.png

IplImage* greyLeftImg= cvLoadImage(filename1,0);

char* filename2="im1.ppm";

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;

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。