www.pudn.com > crackDection.zip > edge.cpp, change:2013-07-31,size:8966b


#include "highgui.h" 
#include "cv.h" 
#include "cxcore.h" 
#include "math.h" 
#include "edge.h" 
 
float max(float x,float y) 
{ 
	float z; 
	if(x>y)z=x; 
	else z=y; 
	return(z); 
} 
//Marr算子 
void log(IplImage *src,IplImage *dst) 
{ 
	//dst = cvCloneImage(src); 
	IplImage* dst1 = cvCreateImage(cvGetSize(src),32,1); 
	IplImage* SmoothImg = cvCloneImage(src); 
	dst =  cvCreateImage(cvGetSize(src),8,1); 
	cvSmooth(src,SmoothImg,CV_GAUSSIAN,3,3);  //对图像做3*3的高斯平滑滤波 
	cvLaplace(SmoothImg,dst1,3); 
	cvConvertScale(dst1,dst);   //将图像转化为8位 
	double min_val = 0;double max_val = 0; 
	cvMinMaxLoc(dst,&min_val,&max_val);   //取图像中的最大最小像素值 
	printf("max_val = %f\nmin_val = %f\n",max_val,min_val); 
	cvNormalize(dst,dst,0,255,CV_MINMAX); //归一化处理 
	//对梯度图加门限,二值化 
 /*	int x,y; 
	char* p = dst->imageData; 
	int w = dst->widthStep; 
	for(x = 0;x<dst->width;x++) 
	{ 
		for(y = 0;y<dst->height;y++) 
		{ 
			if(p[x+y*w]>50) 
				p[x+y*w] = 255; 
			else p[x+y*w] = 0; 
		} 
	}	*/ 
	cvNamedWindow("log",1); 
	cvShowImage("log",dst); 
	cvReleaseImage(&dst1); 
	cvReleaseImage(&SmoothImg); 
 
} 
//Kirsch算子 
void kirsch(IplImage *src,IplImage *dst) 
{ 
	dst = cvCloneImage(src); 
	//cvConvert(src,srcMat); //将图像转化成矩阵处理 
	int x,y; 
	float a,b,c,d; 
	float p1,p2,p3,p4,p5,p6,p7,p8,p9;  
	uchar* ps = (uchar*)src->imageData ; //ps为指向输入图片数据的指针 
	uchar* pd = (uchar*)dst->imageData ; //pd为指向输出图片数据的指针 
	int w = dst->width; 
	int h = dst->height; 
	int step = dst->widthStep; 
 
	for(x = 0;x<w-2;x++)      //取以(x+1,y+1)为中心的9个邻域像素  1 4 7 
	{                                                            // 2 5 8 
		for(y = 0;y<h-2;y++)                                     // 3 6 9 
		{   
			p1=ps[y*step+x]; 
			p2=ps[y*step+(x+1)]; 
			p3=ps[y*step+(x+2)]; 
			p4=ps[(y+1)*step+x]; 
			p5=ps[(y+1)*step+(x+1)]; 
			p6=ps[(y+1)*step+(x+2)]; 
			p7=ps[(y+2)*step+x]; 
			p8=ps[(y+2)*step+(x+1)]; 
			p9=ps[(y+2)*step+(x+2)];//得到(i+1,j+1)周围九个点的灰度值 
 
			a = fabs(float(-5*p1-5*p2-5*p3+3*p4+3*p6+3*p7+3*p8+3*p9));    //计算4个方向的梯度值 
			b = fabs(float(3*p1-5*p2-5*p3+3*p4-5*p6+3*p7+3*p8+3*p9)); 
			c = fabs(float(3*p1+3*p2-5*p3+3*p4-5*p6+3*p7+3*p8-5*p9)); 
			d = fabs(float(3*p1+3*p2+3*p3+3*p4-5*p6+3*p7-5*p8-5*p9)); 
			a = max(a,b);                                         //取各个方向上的最大值作为边缘强度 
			a = max(a,c); 
			a = max(a,d); 
			pd[(y+1)*step+(x+1)] = a; 
		/*	if(a>100) 
			{ 
				pd[(y+1)*step+(x+1)]=255; 
			} 
			else pd[(y+1)*step+(x+1)]=0;*/ 
		} 
	} 
	double min_val = 0, max_val = 0;//取图并显示像中的最大最小像素值 
	cvMinMaxLoc(dst,&min_val,&max_val);    
	printf("max_val = %f\nmin_val = %f\n",max_val,min_val); 
	cvNormalize(dst,dst,0,255,CV_MINMAX); //归一化处理 
	cvNamedWindow("kirsch",1); 
	cvShowImage("kirsch",dst); 
/*	 
	 
	//定义算子的模板 
	float kirsch1[9] =          
	{ 
		-5,3,3, 
		-5,0,3, 
		-5,3,3 
	}; 
	float kirsch2[9] =  
	{ 
		3,3,3, 
		-5,0,3, 
		-5,-5,3 
	}; 
	float kirsch3[9] =          
	{ 
		3,3,3, 
		3,0,3, 
		-5,-5,-5 
	}; 
	float kirsch4[9] =  
	{ 
		3,3,3, 
		3,0,-5, 
		3,-5,-5 
	};*/ 
} 
 
//Prewitt算子,使用卷积公式编写 
void prewitt(IplImage *src,IplImage *dst) 
{ 
	//定义prewitt算子的模板 
	float prewittx[9] =          
	{ 
		-1,0,1, 
		-1,0,1, 
		-1,0,1 
	}; 
	float prewitty[9] =  
	{ 
		1,1,1, 
		0,0,0, 
		-1,-1,-1 
	}; 
	CvMat px;    
	px = cvMat(3,3,CV_32F,prewittx);    
	CvMat py; 
	py = cvMat(3,3,CV_32F,prewitty); 
 
	//为输出图像申请空间 
	IplImage *dstx = cvCreateImage(cvGetSize(src),8,1);  
	IplImage *dsty = cvCreateImage(cvGetSize(src),8,1); 
 
	//对图像使用模板,自动填充边界 
	cvFilter2D(src,dstx,&px,cvPoint(-1,-1));  
	cvFilter2D(src,dsty,&py,cvPoint(-1,-1)); 
 
	//计算梯度,范数为2,注意学习指针的使用方法 
	int i,j,temp; 
	float tempx,tempy;  //定义为浮点型是为了避免sqrt函数引起歧义 
	uchar* ptrx = (uchar*) dstx->imageData; 
	uchar* ptry = (uchar*) dsty->imageData; 
	for(i = 0;i<src->width;i++) 
	{ 
		for(j = 0;j<src->height;j++) 
		{ 
			tempx = ptrx[i+j*dstx->widthStep];   //tempx,tempy表示的是指针所指向的像素 
			tempy = ptry[i+j*dsty->widthStep];  
			temp = (int) sqrt(tempx*tempx+tempy*tempy); 
			/*if(temp>100) temp = 255; 
			else temp = 0;*/ 
			dst->imageData[i+j*dstx->widthStep] = temp; 
		} 
	}	 
	double min_val = 0, max_val = 0;//取图并显示像中的最大最小像素值 
	cvMinMaxLoc(dst,&min_val,&max_val);    
	printf("max_val = %f\nmin_val = %f\n",max_val,min_val); 
	 
	//计算梯度,范数为1 
	//cvAdd(dstx,dsty,dst); 
	cvReleaseImage(&dstx); 
	cvReleaseImage(&dsty); 
	cvNamedWindow("prewitt",1); 
	cvShowImage("prewitt",dst); 
} 
 
//roberts算子求图像梯度提取边缘,输入源图像,输出梯度图 
void roberts(IplImage *src,IplImage *dst) 
{ 
	//为roberts图像申请空间,因为要利用源图像指针中的imageData,因此使用复制方式 
	dst=cvCloneImage(src); 
	int x,y,i,w,h; 
	int temp,temp1; 
 
	uchar* ptr=(uchar*) (dst->imageData ); 
	int ptr1[4]={0}; 
	int indexx[4]={0,1,1,0}; 
	int indexy[4]={0,0,1,1}; 
    w=dst->width; 
	h=dst->height; 
	for(y=0;y<h-1;y++) 
		for(x=0;x<w-1;x++) 
		{ 
 
			for(i=0;i<4;i++)    //取每个2*2矩阵元素的指针      0 | 1 
			{                   //                             3 | 2 
				ptr1[i]= *(ptr+(y+indexy[i])*dst->widthStep+x+indexx[i]); 
				 
			} 
			temp=abs(ptr1[0]-ptr1[2]);    //计算2*2矩阵中0和2位置的差,取绝对值temp 
			temp1=abs(ptr1[1]-ptr1[3]);   //计算2*2矩阵中1和3位置的差,取绝对值temp1 
			temp=(temp>temp1?temp:temp1); //若temp1>temp,则以temp1的值替换temp 
	    	temp= (int)sqrt(float(temp*temp)+float(temp1*temp1));  //输出值 
		/*	if (temp>100) 
				temp=255; 
			else temp=0;  */ 
			*(ptr+y*dst->widthStep+x)=temp;	   //将输出值存放于dst像素的对应位置 
		} 
 
	double min_val = 0,max_val = 0;//取图并显示像中的最大最小像素值 
	cvMinMaxLoc(dst,&min_val,&max_val);    
	printf("max_val = %f\nmin_val = %f\n",max_val,min_val); 
	cvNamedWindow("robert",1); 
	cvShowImage("robert",dst); 
} 
 
//sobel算子求图像梯度提取边缘,输入源图像,输出梯度图 
void sobel(IplImage *src,IplImage *dst) 
{ 
	//为soble微分图像申请空间,创建图片函数 
	IplImage *pSobelImg_dx = cvCreateImage(cvGetSize(src),32,1); 
	IplImage *pSobelImg_dy = cvCreateImage(cvGetSize(src),32,1); 
	IplImage *pSobelImg_dxdy = cvCreateImage(cvGetSize(src), 32,1); 
 
	//用sobel算子计算两个方向的微分 
	cvSobel(src , pSobelImg_dx, 1, 0, 3); 
	cvSobel(src , pSobelImg_dy, 0, 1, 3); 
	 
     //total gradient = sqrt(horizontal*horizontal+vertical*vertical) 
     int i,j; 
     double v1,v2,v; 
     for (i=0;i<src->height;i++) 
     { 
          for (j=0;j<src->width;j++) 
           { 
                    v1 = cvGetReal2D(pSobelImg_dx,i,j); 
                    v2 = cvGetReal2D(pSobelImg_dy,i,j); 
                    v = sqrt(v1*v1+v2*v2); 
				/*	if(v>100) v = 255; 
					else v = 0;*/ 
                    cvSetReal2D(pSobelImg_dxdy,i,j,v); 
           } 
     } 
	cvConvertScale(pSobelImg_dxdy,dst);   //将图像转化为8位 
	double min_val = 0,max_val = 0;//取图并显示像中的最大最小像素值 
	cvMinMaxLoc(pSobelImg_dxdy,&min_val,&max_val);    
	printf("max_val = %f\nmin_val = %f\n",max_val,min_val); 
 
    //归一化 
    cvNormalize(dst,dst,0,255,CV_MINMAX,0); 
 
	//子函数处理完即可释放中间图像 
	cvReleaseImage(&pSobelImg_dx); 
    cvReleaseImage(&pSobelImg_dy); 
	cvReleaseImage(&pSobelImg_dxdy); 
	cvNamedWindow("sobel",1); 
	cvShowImage("sobel",dst); 
} 
 
int EDGE(IplImage* src) 
{ 
	IplImage *pCannyImg = cvCreateImage(cvGetSize(src),8,1); 
	IplImage *pLaplaceImg_32 = cvCreateImage(cvGetSize(src),32,1); 
	IplImage *pLaplaceImg = cvCreateImage(cvGetSize(src),8,1); 
	double min_val = 0,max_val = 0;//取图并显示像中的最大最小像素值 
 
	//canny边缘检测 
	cvCanny(src,pCannyImg,100,150,3), 
	cvNamedWindow("canny",1); 
	cvShowImage("canny",pCannyImg); 
	cvReleaseImage(&pCannyImg); 
 
	//Laplace边缘检测 
	cvLaplace(src,pLaplaceImg_32,5); 
	cvConvertScale(pLaplaceImg_32,pLaplaceImg);   //将图像转化为8位 
	cvMinMaxLoc(pLaplaceImg,&min_val,&max_val);    
	printf("max_val = %f\nmin_val = %f\n",max_val,min_val); 
	cvNormalize(pLaplaceImg,pLaplaceImg,0,255,CV_MINMAX,0); 
	cvNamedWindow("laplace",1); 
	cvShowImage("laplace",pLaplaceImg); 
	cvReleaseImage(&pLaplaceImg); 
 
	//log边缘检测 
	IplImage *pLogImg = cvCreateImage(cvGetSize(src),8,1); 
	log(src,pLogImg); 
	cvReleaseImage(&pLogImg); 
 
	//sobel边缘检测 
	IplImage *pSobelImg = cvCreateImage(cvGetSize(src),8,1); 
	sobel(src,pSobelImg); 
	cvReleaseImage(&pSobelImg); 
 
	//roberts边缘检测 
	IplImage *pRobertsImg = cvCreateImage(cvGetSize(src),8,1); 
	roberts(src,pRobertsImg); 
	cvReleaseImage(&pRobertsImg); 
 
	//prewitt边缘检测 
	IplImage *pPrewittImg = cvCreateImage(cvGetSize(src),8,1); 
	prewitt(src,pPrewittImg); 
	cvReleaseImage(&pPrewittImg); 
 
	//kirsch边缘检测 
	IplImage *pKirschImg = cvCreateImage(cvGetSize(src),8,1); 
	kirsch(src,pKirschImg); 
	cvReleaseImage(&pKirschImg); 
 
	//等待按键 
	cvWaitKey(0); 
 
	//销毁窗口,释放图像 
	cvDestroyAllWindows(); 
	 
	return -1; 
}