代码依赖OpenCV来做一些数据结构和显示的工作,但主要的计算法部分是自己实现的。后面争取依次给出常见的集中边缘提取的算法实现。下次补上原理推到说明。
// Sobel.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "cv.h" #include "highgui.h" #include "math.h" #include "stdio.h" #include "malloc.h" IplImage *image; //声明IplImage指针 int height,width; CvScalar sclr; int sobel_y[9]={1,2,1,0,0,0,-1,-2,-1}; //y方向sobel算子 int sobel_x[9]={1,0,-1,2,0,-2,1,0,-1}; //x方向sobel算子 //显示矩阵BGR inline void cv3DoubleMatPrint( const CvMat* mat ) { int i, j; for( i = 0; i < mat->rows; i++ ) { for( j = 0; j < mat->cols; j++ ) { CvScalar scal = cvGet2D( mat, i, j ); printf( "(%f,%f,%f) ", scal.val[0], scal.val[1], scal.val[2] ); } printf( "\n" ); } } //Sobel算法 void sobel() { int i,j,k; int gray_x=0, gray_y=0, gray; int *data; int temp[9]; data = (int *)malloc(height*width*sizeof(int));//分配内存空间 for(i=0;i<height;i++) //将一点三个数据的矩阵转为一点单数据的矩阵 { for(j=0;j<width;j++) { sclr=cvGet2D(image,i,j); gray=(int)sclr.val[0]; data[i*width+j]=gray; } } for(i=1;i<height-1;i++) { for(j=1;j<width-1;j++) { gray_x=0; gray_y=0; sclr=cvGet2D(image,i,j); temp[0]=data[width*(i-1)+j-1]; temp[1]=data[width*(i-1)+j]; temp[2]=data[width*(i-1)+j+1]; temp[3]=data[width*i+j-1]; temp[4]=data[width*i+j]; temp[5]=data[width*i+j+1]; temp[6]=data[width*(i+1)+j-1]; temp[7]=data[width*(i+1)+j]; temp[8]=data[width*(i+1)+j+1]; for(k=0;k<9;k++) gray_y+=temp[k]*sobel_y[k]; for(k=0;k<9;k++) gray_x+=temp[k]*sobel_x[k]; //sclr.val[0]=(gray_x+gray_y);//生成梯度图 //=======================================// //根据梯度二值化得到提取边缘后的图像 sclr.val[0]= abs(gray_x) + abs(gray_y); //阈值可调整,阈值大则轮廓线条少,阈值小则轮廓线密 if (sclr.val[0]<200) sclr.val[0] = 0; else sclr.val[0] = 255; //=======================================// cvSet2D(image,i,j,sclr); } } free(data); } int main( int argc, char** argv ) { IplImage* img = cvLoadImage("test.jpg"); cvNamedWindow( "img" ); //创建窗口 cvShowImage( "img", img ); //显示图像 image = cvLoadImage( "test.jpg", 0); height=image->height; width=image->width; sobel(); //cvWaitKey(0); //===========================================// //mat = cvGetMat( image, &cvmat ); //cv3DoubleMatPrint( mat ); //===========================================// cvNamedWindow( "Image", 1 ); //创建窗口 cvShowImage( "Image", image ); //显示图像 cvWaitKey(0); //等待按键 cvDestroyWindow( "Image" ); //销毁窗口 cvReleaseImage( &image ); //释放图像 return 0; }