// sobel.cpp : Defines the entry point for the console application. // // Geovany A. Ramirez geoabi@gmail.com // april 2009 #include "stdafx.h" // only for VC++, otherwise remove it #include "cv.h" #include "highgui.h" int dx[3][3] = {{1,0,-1},{2,0,-2},{1,0,-1}}; int dy[3][3] = {{1,2,1},{0,0,0},{-1,-2,-1}}; //******** faster versions ***************** // Sobel operator implementation using inderect access void Sobel_ind_fast( IplImage* img, IplImage* dst) { CvScalar s; for (int i=1; i < img->height-2; i++) for (int j=1; j < img->width-2; j++) { // apply kernel in X and Y directions int sum_x=0; int sum_y=0; for(int m=-1; m<=1; m++) for(int n=-1; n<=1; n++) { s=cvGet2D(img,i+m,j+n); // get the (i,j) pixel value sum_x+=(int)s.val[0]*dx[m+1][n+1]; sum_y+=(int)s.val[0]*dy[m+1][n+1]; } int sum=abs(sum_x)+abs(sum_y); s.val[0]=(sum>255)?255:sum; cvSet2D(dst,i,j,s); // set the (i,j) pixel value } } // Sobel operator implementation using direct access using a pointer void Sobel_dir_fast( IplImage* img, IplImage* dst) { int step = img->widthStep/sizeof(uchar); uchar* data = (uchar *)img->imageData; uchar* data_dst = (uchar *)dst->imageData; int s; for (int i=1; i < img->height-2; i++) for (int j=1; j < img->width-2; j++) { // apply kernel in X ans Y direction int sum_x=0; int sum_y=0; for(int m=-1; m<=1; m++) for(int n=-1; n<=1; n++) { s=data[(i+m)*step+j+n]; // get the (i,j) pixel value sum_x+=s*dx[m+1][n+1]; sum_y+=s*dy[m+1][n+1]; } int sum=abs(sum_x)+abs(sum_y); data_dst[i*step+j]=(sum>255)?255:sum; // set the (i,j) pixel value } } //******** end of faster versions ***************** // Sobel operator implementation using inderect access void Sobel_ind( IplImage* img, IplImage* dst) { CvScalar s; for (int i=1; i < img->height-2; i++) for (int j=1; j < img->width-2; j++) { // apply kernel in X direction int sum_x=0; for(int m=-1; m<=1; m++) for(int n=-1; n<=1; n++) { s=cvGet2D(img,i+m,j+n); // get the (i,j) pixel value sum_x+=(int)s.val[0]*dx[m+1][n+1]; } // apply kernel in Y direction int sum_y=0; for(int m=-1; m<=1; m++) for(int n=-1; n<=1; n++) { s=cvGet2D(img,i+m,j+n); // get the (i,j) pixel value sum_y+=(int)s.val[0]*dy[m+1][n+1]; } int sum=abs(sum_x)+abs(sum_y); if (sum>255) sum=255; s.val[0]=sum; cvSet2D(dst,i,j,s); // set the (i,j) pixel value } } // Sobel operator implementation using direct access using a pointer void Sobel_dir( IplImage* img, IplImage* dst) { int step = img->widthStep/sizeof(uchar); uchar* data = (uchar *)img->imageData; uchar* data_dst = (uchar *)dst->imageData; int s; for (int i=1; i < img->height-2; i++) for (int j=1; j < img->width-2; j++) { // apply kernel in X direction int sum_x=0; for(int m=-1; m<=1; m++) for(int n=-1; n<=1; n++) { s=data[(i+m)*step+j+n]; // get the (i,j) pixel value sum_x+=s*dx[m+1][n+1]; } // apply kernel in Y direction int sum_y=0; for(int m=-1; m<=1; m++) for(int n=-1; n<=1; n++) { s=data[(i+m)*step+j+n]; // get the (i,j) pixel value sum_y+=s*dy[m+1][n+1]; } int sum=abs(sum_x)+abs(sum_y); if (sum>255) sum=255; data_dst[i*step+j]=sum; // set the (i,j) pixel value } } // display the Sobel output for the indicate sobel implementation void show_sobel(IplImage* image, int v, int sh) { IplImage *img = 0; IplImage *img_edg = 0; if( sh==1) cvShowImage( "Original image", image ); img=cvCreateImage( cvSize(image->width,image->height), 8, 1 ); if ( image->nChannels!=1) cvCvtColor( image, img, CV_BGR2GRAY ); else cvCopy( image, img); img_edg = cvCreateImage( cvSize(image->width,image->height), 8, 1 ); double t = (double)cvGetTickCount(); const char* win_name; if (v==1) // inderect access { Sobel_ind_fast(img,img_edg); win_name="indirect access"; } else if(v==2) // direct access using a pointer { Sobel_dir_fast(img,img_edg); win_name="direct access "; } else // Default: opencv implementation { cvSobel( img, img_edg, 0, 1, 3 ); win_name="OpenCV function"; } t = (double)cvGetTickCount() - t; printf( "running time using %s = %gms\n",win_name, t/((double)cvGetTickFrequency()*1000.)); cvShowImage( win_name, img_edg ); cvReleaseImage( &img ); cvReleaseImage( &img_edg ); } int _tmain(int argc, _TCHAR* argv[]) { CvCapture* capture = 0; IplImage *image = 0; int v=0; cvNamedWindow( "Original image", 1 ); cvNamedWindow( "indirect access", 1 ); cvNamedWindow( "direct access ", 1 ); cvNamedWindow( "OpenCV function", 1 ); capture = cvCaptureFromCAM( 0 ); // Webcam if( capture ) { IplImage *frame, *frame_copy = 0; for(;;) { if( !cvGrabFrame( capture )) break; frame = cvRetrieveFrame( capture ); if( !frame ) break; if( !frame_copy ) frame_copy = cvCreateImage( cvSize(frame->width,frame->height), IPL_DEPTH_8U, frame->nChannels ); if( frame->origin == IPL_ORIGIN_TL ) cvCopy( frame, frame_copy, 0 ); else cvFlip( frame, frame_copy, 0 ); show_sobel( frame_copy, v, 1); if( cvWaitKey( 10 ) > 0 ) break; } cvReleaseImage( &frame_copy ); cvReleaseCapture( &capture ); } else { //const char* filename = (char*)"C:/Program Files/OpenCV/samples/c/box.png"; const char* filename = (char*)"C:/Program Files/OpenCV/samples/c/fruits.jpg"; image = cvLoadImage( filename, 1 ); if (!image) printf( "can not read the image file\n"); else { show_sobel( image ,1, 1); show_sobel( image ,2, 0); show_sobel( image ,3, 0); cvWaitKey(0); } } return 0; }