注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

*^^* 寂寞的whitebaby

欢迎来到我的家,充满回忆的地方

 
 
 

日志

 
 
关于我

いǒDê個性伱惹吥起                 ヤ 無限囂張.習慣寂寞‰〆┈

基于OpenCV的两种Sobel实现  

2011-03-02 17:21:19|  分类: openCV |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Sobel算子主要用于边缘检测。如果以A代表原始图像,Gx及Gy分别代表经横向及纵向边缘检测的图像,其公式如下:

 计算梯度的大小:

计算梯度方向:

前段时间用到Sobel,在VS2008下,分别用OpenCV2.0完成了两种实现,后者较快。测试图像“1.jpg”如下:

实现1(完全借助OpenCV的函数,较慢):

#include "stdafx.h"

#include "highgui.h"

#include "cv.h"

 

void Soble(IplImage *img,IplImage* gradientImage)

{

         IplImage* H = cvCreateImage(cvGetSize(img), 32,1);

         IplImage* V = cvCreateImage(cvGetSize(img), 32,1);

         IplImage* HV = cvCreateImage(cvGetSize(img), 32,1);

 

         //both horizontal and vertical gradient

         cvSobel(img,H,0,1,3); 

         cvSobel(img,V,1,0,3);

 

         //total gradient = sqrt(horizontal*horizontal+vertical*vertical)

         int i,j;

         double v1,v2,v;

         for (i=0;i<img->height;i++)

         {

                  for (j=0;j<img->width;j++)

                   {

                            v1 = cvGetReal2D(H,i,j);

                            v2 = cvGetReal2D(V,i,j);

                            v = sqrt(v1*v1+v2*v2);

 

                            cvSetReal2D(HV,i,j,v);

                   }

         }

         cvNormalize(HV,gradientImage,0,255,CV_MINMAX,0);

 

         cvReleaseImage(&H);

         cvReleaseImage(&V);

         cvReleaseImage(&HV);

}

int _tmain(int argc, _TCHAR* argv[])

{

         IplImage * img = cvLoadImage("1.jpg",1);

         IplImage *grayImage = cvCreateImage(cvGetSize(img), 8, 1);

         IplImage *gradientImage = cvCreateImage(cvGetSize(img),8,1);

 

         cvCvtColor(img, grayImage, CV_BGR2GRAY);  // color to gray

 

         double t = cvGetTickCount();

         Soble(grayImage,gradientImage); 

         t = (cvGetTickCount()-t)/1000000;

         printf("time: %4.4f\n", t);

 

         cvNamedWindow("grayImage",1);

         cvShowImage("grayImage",grayImage);

         cvNamedWindow("gradientImage",1);

         cvShowImage("gradientImage",gradientImage);

 

         cvWaitKey(0);

         cvReleaseImage(&img);

         cvReleaseImage(&grayImage);

         cvReleaseImage(&gradientImage);

         return 0;

}

 

效果图如下:

  

实现2(借助指针,较快): 

#include "stdafx.h"

#include "highgui.h"

#include "cv.h"

 

int FastSobel(unsigned char *in, int width, int height, int widthStep,

                               unsigned char *edg, unsigned char *ang)

{

         int i,j;

 

         unsigned char *inPtr = NULL;

         unsigned char *inPtr1 = NULL;

         unsigned char *inPtr2 = NULL;

         unsigned char *inPtr3 = NULL;

         unsigned char *inPtr4 = NULL;

         unsigned char *inPtr5 = NULL;

         unsigned char *inPtr6 = NULL;

 

         int *pEdgeX = (int *)calloc(width*height, sizeof(int));

         int *pEdgeY = (int *)calloc(width*height, sizeof(int));

         int *pEdgeXPtr = NULL;

         int *pEdgeYPtr = NULL;

 

         unsigned char *angPtr = NULL;

         unsigned char *edgPtr = NULL;

 

         // this is heuristic, and it should add receptive area

         int widH = 1;

         int widV = 1;

         widV *= widthStep;

 

         for (i=1;i<height-1;i++)

         {

                   pEdgeXPtr = pEdgeX + i*width + 1;

                   inPtr = in + i * widthStep + 1;

                   inPtr1 = inPtr + widH - widV;

                   inPtr2 = inPtr + widH;

                   inPtr3 = inPtr + widH + widV;

                   inPtr4 = inPtr - widH - widV;

                   inPtr5 = inPtr - widH;

                   inPtr6 = inPtr - widH + widV;

                   for (j=1;j<width-1;j++, pEdgeXPtr++)

                   {

                            *pEdgeXPtr

                                     = (*inPtr1++ * 1 + (int)*inPtr2++ * 2 + *inPtr3++ * 1)

                                     - (*inPtr4++ * 1 + (int)*inPtr5++ * 2 + *inPtr6++ * 1);

                   }

         }

 

         for (i=1;i<height-1;i++)

         {

                   pEdgeYPtr = pEdgeY + i*width + 1;

                   inPtr = in + i * widthStep + 1;

                   inPtr1 = inPtr + widV - widH;

                   inPtr2 = inPtr + widV;

                   inPtr3 = inPtr + widV + widH;

                   inPtr4 = inPtr - widV - widH;

                   inPtr5 = inPtr - widV;

                   inPtr6 = inPtr - widV + widH;

                   for (j=1;j<width-1;j++, pEdgeYPtr++)

                   {

                            *pEdgeYPtr

                                     = (*inPtr1++ * 1 + (int)*inPtr2++ * 2 + *inPtr3++ * 1)

                                     - (*inPtr4++ * 1 + (int)*inPtr5++ * 2 + *inPtr6++ * 1);

                   }

         }

 

         for (i=1;i<height-1;i++)

         {

                   pEdgeXPtr = pEdgeX + i*width + 1;

                   pEdgeYPtr = pEdgeY + i*width + 1;

                   angPtr = ang + i * widthStep + 1;

                   edgPtr = edg + i * widthStep + 1;

                   for (j=1; j<width-1; j++, pEdgeYPtr++, pEdgeXPtr++, angPtr++, edgPtr++)

                   {

                            *angPtr = atan2((double)*pEdgeYPtr,(double)*pEdgeXPtr)*180/3.141592654;

                            *edgPtr = min(255,sqrt((float)*pEdgeXPtr**pEdgeXPtr + (float)*pEdgeYPtr**pEdgeYPtr)/2);

                   }

         }

 

         free(pEdgeY); pEdgeY = NULL;

         free(pEdgeX); pEdgeX = NULL;

 

         return 0;

}

int _tmain(int argc, _TCHAR* argv[])

{

         IplImage * img = cvLoadImage("1.jpg",1);

 

         IplImage *grayImage = cvCreateImage(cvSize(img->width, img->height), 8, 1);

         IplImage *gradientImage = cvCreateImage(cvSize(img->width, img->height), 8, 1);

         IplImage *anglImage = cvCreateImage(cvSize(img->width, img->height), 8, 1);

 

         cvCvtColor(img, grayImage, CV_BGR2GRAY);  // color to gray

         double t = cvGetTickCount();

 

         FastSobel((unsigned char*)grayImage->imageData, grayImage->width, grayImage->height, grayImage->widthStep,

                   (unsigned char*)gradientImage->imageData, (unsigned char*)anglImage->imageData);

 

         t = (cvGetTickCount()-t)/1000000;

         printf("time: %4.4f\n", t);

 

         cvNamedWindow("grayImage",1);

         cvShowImage("grayImage",grayImage);

 

         cvNamedWindow("gradientImage",1);

         cvShowImage("gradientImage",gradientImage);

 

         cvWaitKey(0);

         cvReleaseImage(&img);

         cvReleaseImage(&grayImage);

         cvReleaseImage(&gradientImage);

         cvReleaseImage(&anglImage);

         return 0;

}

效果图如下:

  评论这张
 
阅读(2790)| 评论(3)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018