sobel_result

實作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;
 }
}