實作sobel edge detector,梯度計算使用|▽xf|+|▽yf|。
門檻值T為30,梯度大於或等於30則視為邊界並以白點(255)表示,反之黑點(0)。
#include <cv.h> #include <highgui.h> #include <stdio.h> using namespace cv; using namespace std; void Sobel_x(Mat image1);//image1 represent original image void Sobel_y(Mat image1); void Sobel_test(Mat image2,int array1[512][512],int array2[512][512]);//image2 represent result image int rows,cols; int CXMatrix[514][514];//copy original image and expand size to let sobel_x to use(CX) int CYMatrix[514][514];//copy original image and expand size to let sobel_y to use(CY) int XMatrix[512][512];//calculate soble_x results(X) int YMatrix[512][512];//calculate soble_y results(Y) int RMatrix[512][512];//results of sobel_test(R) int main(){ Mat image = imread("Lena.bmp", CV_LOAD_IMAGE_GRAYSCALE); rows=image.rows;//height cols=image.cols;//width Mat Sobel_image=Mat(rows,cols,CV_8UC1); printf("rows=%d\n",rows); printf("cols=%d\n",cols); Sobel_x(image); Sobel_y(image); Sobel_test(Sobel_image,XMatrix,YMatrix); namedWindow( "Lena", CV_WINDOW_AUTOSIZE );//顯示原image圖 imshow( "Lena", image); namedWindow( "sobel edge detector image", CV_WINDOW_AUTOSIZE );//顯示測邊圖 imshow( "sobel edge detector image", Sobel_image); waitKey(0); return 0; } void Sobel_x(Mat image1)//sobel x operator { int sobel_x_matrix[3][3]={{-1,0,1},{-2,0,2},{-1,0,1}}; for(int i=1;i<=rows;i++)//1~512 for(int j=1;j<=cols;j++) { CXMatrix[i][j]=image1.at<unsigned char>(i-1,j-1); } for(int i=1;i<=rows;i++)//i=j=1~512 //copy left and right //use image view to see for(int j=1;j<=cols;j++) { if(j==1) CXMatrix[i-1][j]=image1.at<unsigned char>(i-1,j-1); if(j==cols) CXMatrix[i+1][j]=image1.at<unsigned char>(i-1,j-1); } for(int i=0;i<=rows+1;i++)//i=0~513,j=1~512 //copy up and down //use CXMatrix view to see for(int j=1;j<=cols;j++) { if(i==1) CXMatrix[i][j-1]=CXMatrix[i][j]; if(i==rows) CXMatrix[i][j+1]=CXMatrix[i][j]; } //Now , we are finish to build CXMatrix for(int i=1;i<=rows;i++) //use image view to see for(int j=1;j<=cols;j++) { int sum=0; for(int m=i-1;m<=i+1;m++)//3*3 by sobel_x_matrix { for(int n=j-1;n<=j+1;n++) { sum=sum+CXMatrix[m][n]*sobel_x_matrix[m-i+1][n-j+1]; } XMatrix[i-1][j-1]=sum;//(0,0)to(511,511) } } } void Sobel_y(Mat image1)//sobel y operator { int sobel_y_matrix[3][3]={{-1,-2,-1},{0,0,0},{1,2,1}}; for(int i=1;i<=rows;i++)//1~512 for(int j=1;j<=cols;j++) { CYMatrix[i][j]=image1.at<unsigned char>(i-1,j-1); } for(int i=1;i<=rows;i++)//i=j=1~512 //copy left and right //use image view to see for(int j=1;j<=cols;j++) { if(j==1) CYMatrix[i-1][j]=image1.at<unsigned char>(i-1,j-1); if(j==cols) CYMatrix[i+1][j]=image1.at<unsigned char>(i-1,j-1); } for(int i=0;i<=rows+1;i++)//i=0~513,j=1~512 //copy up and down //use CYMatrix view to see for(int j=1;j<=cols;j++) { if(i==1) CYMatrix[i][j-1]=CYMatrix[i][j]; if(i==rows) CYMatrix[i][j+1]=CYMatrix[i][j]; } //Now , we are finish to build CYMatrix for(int i=1;i<=rows;i++) //use image view to see for(int j=1;j<=cols;j++) { int sum=0; for(int m=i-1;m<=i+1;m++)//3*3 by sobel_y_matrix { for(int n=j-1;n<=j+1;n++) { sum=sum+CYMatrix[m][n]*sobel_y_matrix[m-i+1][n-j+1]; } YMatrix[i-1][j-1]=sum;//(0,0)to(511,511) } } } void Sobel_test(Mat image2,int array1[512][512],int array2[512][512])//Use formula |X|+|Y|>=T to set 255 or 0 { int T=128;//Assume set Threshold to 128 //you can set 80 is also clear to see it for(int i=0;i<rows;i++) for(int j=0;j<cols;j++) { int x,y; if(array1[i][j]<0) //test whether array1 is negative or not . If negative , choose |array1| 即取絕對值 x=array1[i][j]*(-1); else x=array1[i][j]; if(array2[i][j]<0) //test whether |array2| or not . If negative , choose |array2| y=array2[i][j]*(-1); else y=array2[i][j]; if(x+y>=T) image2.at<unsigned char>(i,j)=255; else image2.at<unsigned char>(i,j)=0; } }