www.pudn.com > stereo.rar > CaliDoc.cpp


// CaliDoc.cpp : implementation of the CCaliDoc class 
// 
 
#include "stdafx.h" 
#include  
#include "Cali.h" 
#include "CDIB.h" 
#include "Corner.h" 
#include "PriorityQueue.h" 
#include "CaliDoc.h" 
 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CCaliDoc 
 
IMPLEMENT_DYNCREATE(CCaliDoc, CDocument) 
 
BEGIN_MESSAGE_MAP(CCaliDoc, CDocument) 
	//{{AFX_MSG_MAP(CCaliDoc) 
	ON_COMMAND(ID_CALI_CORNERDETE, OnCaliCornerdete) 
	ON_COMMAND(ID_CALI_INICALI, OnCaliInicali) 
	ON_COMMAND(ID_CALI_PROPAGATION, OnCaliPropagation) 
	ON_COMMAND(ID_CALI_WHOLE, OnCaliWhole) 
	ON_COMMAND(ID_CALI_RGBTOGRAY, OnCaliRgbtogray) 
	ON_COMMAND(ID_READ_LEFT, OnReadLeft) 
	ON_COMMAND(ID_READ_RIGHT, OnReadRight) 
	ON_COMMAND(ID_CALI_DISPARITY, OnCaliDisparity) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CCaliDoc construction/destruction 
 
CCaliDoc::CCaliDoc() 
{ 
	processing=-1; 
	mapsafterpro=NULL; 
 
} 
 
CCaliDoc::~CCaliDoc() 
{ 
} 
 
BOOL CCaliDoc::OnNewDocument() 
{ 
	if (!CDocument::OnNewDocument()) 
		return FALSE; 
 
	// TODO: add reinitialization code here 
	// (SDI documents will reuse this document) 
 
	return TRUE; 
} 
 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CCaliDoc serialization 
 
void CCaliDoc::Serialize(CArchive& ar) 
{ 
	if (ar.IsStoring()) 
	{ 
		// TODO: add storing code here 
	} 
	else 
	{ 
		// TODO: add loading code here 
	} 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CCaliDoc diagnostics 
 
#ifdef _DEBUG 
void CCaliDoc::AssertValid() const 
{ 
	CDocument::AssertValid(); 
} 
 
void CCaliDoc::Dump(CDumpContext& dc) const 
{ 
	CDocument::Dump(dc); 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CCaliDoc commands 
 
void CCaliDoc::OnCaliCornerdete()  
{ 
	BeginWaitCursor(); 
	numofcorner1=CornerDetection(m_dib1,0,corner1); 
	numofcorner2=CornerDetection(m_dib2,1,corner2); 
	processing=1; 
	UpdateAllViews(NULL); 
	EndWaitCursor(); 
	 
} 
 
void CCaliDoc::OnCaliInicali()  
{ 
	BeginWaitCursor(); 
	InitialCalibration(m_dib1, m_dib2,corner1,corner2, numofcorner1, numofcorner2, seedq); 
	numofseeds=seedq.size(); 
	seeds=new MatchPoint[numofseeds]; 
	int i=0; 
	while(!seedq.empty()){ 
		seeds[i]=seedq.top(); 
		seedq.pop(); 
		i++; 
	} 
	for(i=0;ibiWidth*image.m_lpBMIH->biHeight]; 
	dy=new int[image.m_lpBMIH->biWidth*image.m_lpBMIH->biHeight]; 
    m=(size-1)/2; 
    for (i=0;ibiHeight-1;i++) 
	{ 
		for (j=1;jbiWidth-1;j++) 
		{ 
		 
			dx[i*(image.m_lpBMIH->biWidth)+j]=(-1)*image.GetPixel(j-1,i-1).rgbRed+image.GetPixel(j+1,i-1).rgbRed+ 
				(-1)*image.GetPixel(j-1,i).rgbRed+image.GetPixel(j+1,i).rgbRed+ 
				(-1)*image.GetPixel(j-1,i+1).rgbRed+image.GetPixel(j+1,i+1).rgbRed;//dx 
			dy[i*(image.m_lpBMIH->biWidth)+j]=(-1)*image.GetPixel(j-1,i-1).rgbRed+(-1)*image.GetPixel(j,i-1).rgbRed+ 
				(-1)*image.GetPixel(j+1,i-1).rgbRed+image.GetPixel(j-1,i+1).rgbRed+ 
				image.GetPixel(j,i+1).rgbRed+image.GetPixel(j+1,i+1).rgbRed;//dy 
		} 
	} 
 //smooth guassion 
	long double Ix,Iy,Ixy,det_c,trace_c; 
	int temp; 
	int num=0; 
	double *r; 
	r=new double[image.m_lpBMIH->biWidth*image.m_lpBMIH->biHeight]; 
	 
	for (i=2;i<(image.m_lpBMIH->biHeight)-1;i++) 
	{ 
		for (j=2;j<(image.m_lpBMIH->biWidth)-1;j++) 
		{ 
			for (Ix=0,Iy=0,Ixy=0,di=0;dibiWidth)+(j-m+dj)]*dx[(i-m+di)*(image.m_lpBMIH->biWidth)+(j-m+dj)]; 
					Iy+=mask[di][dj]*dy[(i-m+di)*(image.m_lpBMIH->biWidth)+(j-m+dj)]*dy[(i-m+di)*(image.m_lpBMIH->biWidth)+(j-m+dj)]; 
					Ixy+=mask[di][dj]*dx[(i-m+di)*(image.m_lpBMIH->biWidth)+(j-m+dj)]*dy[(i-m+di)*(image.m_lpBMIH->biWidth)+(j-m+dj)]; 
				} 
			} 
			det_c=Ix*Iy-Ixy*Ixy; 
			trace_c=Ix+Iy; 
 
			if (det_c==0) 
			   det_c=1e-300; 
			if (trace_c==0) 
				trace_c=1e-150; 
		   r[i*(image.m_lpBMIH->biWidth)+j]=trace_c/det_c; 
			 
 
		} 
	} 
	for(i=6; ibiHeight-6; i++) 
	{ 
		for(j=6; jbiWidth-6; j++) 
		{ 
			if(r[i*(image.m_lpBMIH->biWidth)+j]>R)  
				continue; 
			for(temp=1, di=-3; di<=3; di++) 
			{ 
				for(dj=-3; dj<=3; dj++)  
				{ 
					if(!(di==0 && dj==0) && r[i*(image.m_lpBMIH->biWidth)+j]>=r[(i+di)*(image.m_lpBMIH->biWidth)+(j+dj)]) 
					{  
						temp=0;  
						di=4;  
						break;  
					} 
				} 
			} 
			if(temp==1 && num0) 
	{ 
		corner=new CCorner[num]; 
    	memcpy(corner, cor, sizeof(CCorner)*num); 
	} 
	return(num); 
 
} 
 
 
void CCaliDoc::OnCaliRgbtogray()  
{ 
	RgbtoGray(m_dib1); 
	RgbtoGray(m_dib2); 
	UpdateAllViews(NULL); 
	 
} 
 
void CCaliDoc::RgbtoGray(CDib &image) 
{ 
	int i,j; 
	for(i=0;ibiHeight;i++){ 
		for(j=0;jbiWidth;j++){ 
			BYTE Y; 
			Y=(BYTE)(0.299*image.GetPixel(j,i).rgbRed+0.587*image.GetPixel(j,i).rgbGreen+0.114*image.GetPixel(j,i).rgbBlue); 
			RGBQUAD cColor; 
			cColor.rgbRed=Y; 
			cColor.rgbBlue=Y; 
			cColor.rgbGreen=Y; 
			image.SetPixel(j,i,cColor); 
		} 
	} 
} 
 
void CCaliDoc::OnReadLeft()  
{ 
	CFileDialog  dilg(TRUE, NULL, "*.bmp",    //OPENFILENAME 
 	                  OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, 
 	                  "Bmp Files (*.bmp)|All Files (*.*)|*.*||"); 
 	                                                
 	if(dilg.DoModal() != IDOK) 
 		return; 
  
    CString lpszPathName = dilg.GetPathName(); 
	 
	CFile cf; 
	CFileException e; 
    
	if (!cf.Open(lpszPathName,CFile::modeRead, &e)) 
	{ 
		::AfxMessageBox("Cannot open the file!"); 
	} 
	// 更改光标 
	BeginWaitCursor(); 
 
	// 读取图象 
	if(!m_dib1.Read(&cf)){ 
		// 恢复光标形状 
 		EndWaitCursor();	 		 
 		// 返回 
 		return; 
	} 
	cf.Close(); 
 
	 
	processing=0; 
	UpdateAllViews(NULL); 
} 
 
void CCaliDoc::OnReadRight()  
{ 
		CFileDialog  dilg(TRUE, NULL, "*.bmp",    //OPENFILENAME 
 	                  OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, 
 	                  "Bmp Files (*.bmp)|All Files (*.*)|*.*||"); 
 	                                                
 	if(dilg.DoModal() != IDOK) 
 		return; 
  
    CString lpszPathName = dilg.GetPathName(); 
	 
	CFile cf; 
	CFileException e; 
    
	if (!cf.Open(lpszPathName,CFile::modeRead, &e)) 
	{ 
		::AfxMessageBox("Cannot open the file!"); 
	} 
	// 更改光标 
	BeginWaitCursor(); 
 
	// 读取图象 
	if(!m_dib2.Read(&cf)){ 
		// 恢复光标形状 
 		EndWaitCursor();	 		 
 		// 返回 
 		return; 
	} 
	cf.Close(); 
	CFile cf2; 
	CFileException e2; 
    
	if (!cf2.Open(lpszPathName,CFile::modeRead, &e2)) 
	{ 
		::AfxMessageBox("Cannot open the file!"); 
	} 
	if(!m_dib2Copy.Read(&cf2)){ 
		// 恢复光标形状 
 		EndWaitCursor();	 		 
 		// 返回 
 		return; 
	} 
	cf2.Close(); 
	processing=0; 
	UpdateAllViews(NULL); 
	 
} 
 
 
void CCaliDoc::InitialCalibration(CDib &left, CDib &right, CCorner *&corner1,CCorner *&corner2, const int leftnum, const int rightnum, priorqueue &seed) 
{ 
	double seedthreshold=0.8; 
	if(leftnum<3||rightnum<3) 
	{ 
		::AfxMessageBox("lack of corners !!"); 
		return; 
	} 
	int i,matchleftx,matchlefty,matchrightx,matchrighty; 
	double matchscore; 
	MatchPoint aseed; 
	int *cornerleftx=new int[leftnum]; 
	int *cornerlefty=new int[leftnum]; 
	int *cornerrightx=new int[rightnum]; 
	int *cornerrighty=new int[rightnum]; 
	 
	for(i=0;imatchscore) 
		{ 
			matchscore=temp; 
			matchrightx=cornerrightx[i]; 
			matchrighty=cornerrighty[i]; 
		} 
	} 
 
} 
 
double CCaliDoc::zncc(const int w, CDib &left, int leftx, int lefty, CDib &right, int rightx, int righty) 
{ 
	double result=0,squareleft=0,squareright=0,leftright=0,meanleft,meanright,sumleft=0,sumright=0; 
	int i,j; 
	int leftw=left.m_lpBMIH->biWidth; 
	int lefth=left.m_lpBMIH->biHeight; 
	int rightw=right.m_lpBMIH->biWidth; 
	int righth=right.m_lpBMIH->biHeight; 
	if(leftx<(w-1)/2||rightx<(w-1)/2||leftx>(leftw-1-(w-1)/2)||rightx>(rightw-1-(w-1)/2)||lefty<(w-1)/2||righty<(w-1)/2||lefty>(lefth-1-(w-1)/2)||righty>(righth-1-(w-1)/2)) 
	{ 
		//cerr<<"the points is too close to the edge of the image (smaller than the window width)"<biHeight*left.m_lpBMIH->biWidth]; 
	rightmatched=new int[right.m_lpBMIH->biHeight*right.m_lpBMIH->biWidth];//用于标记(u,u')是否已经被匹配,若匹配,则在左图u的位置赋1,右图u'的位置赋1 
	for(i=0;ibiHeight;i++) 
	{ 
		for(j=0;jbiWidth;j++) 
		{ 
			leftmatched[i*left.m_lpBMIH->biHeight+j]=0; 
		} 
	} 
	for(i=0;ibiHeight;i++) 
	{ 
		for(j=0;jbiWidth;j++) 
		{ 
			rightmatched[i*right.m_lpBMIH->biHeight+j]=0; 
		} 
	} 
	MatchPoint apoint,candidatepoint,newpoint; 
	priorqueue Localset; 
	while(!seed.empty()) 
	{/* 
		//找出zncc-best匹配对  
		MatchPoint *seedt; 
		int seedsize=seed.size(); 
		seedt=new MatchPoint[seedsize]; 
		for(i=0;iznccscore){ 
				znccscore=seedt[i].matchscore; 
				largestscorei=i; 
			} 
		} 
		if(largestscorei!=seedsize-1) 
		{ 
			MatchPoint mt=seedt[seed.size()-1]; 
			seedt[seedsize-1]=seedt[largestscorei]; 
			seedt[largestscorei]=mt; 
		} 
		for(i=0;it) 
					{ 
						for(l=-(neighborwindow-1)/2;l<(neighborwindow+1)/2;l++) 
						{ 
							for(m=-(neighborwindow-1)/2;m<(neighborwindow+1)/2;m++)//对右图象素(apoint.rightx+l,apoint.righty+m) 
							{ 
								if(!((l-i)>epslong||(l-i)<-epslong||(m-j)>epslong||(m-j)<-epslong))//在N(x,x')内增长 
								{ 
									if(s(right,apoint.rightx+l,apoint.righty+m)>t) 
									{ 
										score=zncc(propagationwindow,left,apoint.leftx+i,apoint.lefty+j,right,apoint.rightx+l,apoint.righty+m); 
										if(score>z) 
										{ 
											candidatepoint.leftx=apoint.leftx+i; 
											candidatepoint.lefty=apoint.lefty+j; 
											candidatepoint.rightx=apoint.rightx+l; 
											candidatepoint.righty=apoint.righty+m; 
											candidatepoint.matchscore=score; 
											Localset.push(candidatepoint); 
										} 
									}								 
								}							 
							} 
						}	 
					}					 
				} 
			} 
			while(!Localset.empty()) 
			{ 
				newpoint.leftx=Localset.top().leftx; 
				newpoint.lefty=Localset.top().lefty; 
				newpoint.rightx=Localset.top().rightx; 
				newpoint.righty=Localset.top().righty; 
				newpoint.matchscore=Localset.top().matchscore; 
				Localset.pop(); 
				if(leftmatched[newpoint.leftx*left.m_lpBMIH->biHeight+newpoint.lefty]!=1&&rightmatched[newpoint.rightx*right.m_lpBMIH->biHeight+newpoint.righty]!=1)//此点未被匹配过,可以加入Map 
				{ 
					ResultMap.push_front(newpoint); 
					seed.push(newpoint); 
					leftmatched[newpoint.leftx*left.m_lpBMIH->biHeight+newpoint.lefty]=1; 
					rightmatched[newpoint.rightx*right.m_lpBMIH->biHeight+newpoint.righty]=1; 
			 
				}		 
			}		 
		} 
		//delete[] seedt; 
	} 
	delete[] leftmatched; 
	delete[] rightmatched; 
 
} 
 
BOOL CCaliDoc::fitsize(const int w, CDib &left, CDib &right, int leftx, int lefty, int rightx, int righty) 
{ 
	return !(leftx<(w-1)/2||rightx<(w-1)/2||leftx>(left.m_lpBMIH->biWidth-1-(w-1)/2)||rightx>(right.m_lpBMIH->biWidth-1-(w-1)/2)||lefty<(w-1)/2||righty<(w-1)/2||lefty>(left.m_lpBMIH->biHeight-1-(w-1)/2)||righty>(right.m_lpBMIH->biHeight-1-(w-1)/2)); 
 
} 
 
double CCaliDoc::s(CDib &image, int x, int y) 
{ 
	if(y==image.m_lpBMIH->biHeight){ 
		int stop=0; 
	} 
	double result=0; 
	if(x<0&&x>=image.m_lpBMIH->biWidth&&y<0&&y>=image.m_lpBMIH->biHeight) 
		return result; 
	if(x>0&&xbiWidth&&y>=0&&ybiHeight) 
	{ 
		if(fabs(image.GetPixel(x-1,y).rgbRed-image.GetPixel(x,y).rgbRed)>result) 
		{ 
			result=fabs(image.GetPixel(x-1,y).rgbRed-image.GetPixel(x,y).rgbRed)/255; 
		} 
	} 
	if(x>=0&&xbiWidth-1&&y>=0&&ybiHeight) 
	{ 
		if(fabs(image.GetPixel(x+1,y).rgbRed-image.GetPixel(x,y).rgbRed)>result) 
		{ 
			result=fabs(image.GetPixel(x+1,y).rgbRed-image.GetPixel(x,y).rgbRed)/255; 
		} 
	} 
	if(y>0&&ybiHeight&&x>=0&&xbiWidth) 
	{ 
		if(fabs(image.GetPixel(x,y-1).rgbRed-image.GetPixel(x,y).rgbRed)>result) 
		{ 
			result=fabs(image.GetPixel(x,y-1).rgbRed-image.GetPixel(x,y).rgbRed)/255; 
		} 
	} 
	if(y>=0&&ybiHeight-1&&x>=0&&xbiWidth) 
	{ 
		if(fabs(image.GetPixel(x,y+1).rgbRed-image.GetPixel(x,y).rgbRed)>result) 
		{ 
			result=fabs(image.GetPixel(x,y+1).rgbRed-image.GetPixel(x,y).rgbRed)/255; 
		} 
	} 
	return result; 
 
} 
 
void CCaliDoc::OnCaliDisparity()  
{ 
	int i; 
	if(!mapsafterpro) 
	{ 
		AfxMessageBox("no corresponding points to output!!!"); 
		return; 
	} 
	int disp,max=-2000,min=2000; 
 
	for(i=0;imax) 
		max=disp; 
		if(dispmin) 
	{ 
		for(i=0;i