收入囊中
  • 差分在边缘检測的角色
  • Sobel算子
  • OpenCV sobel函数
  • OpenCV Scharr函数
  • prewitt算子
  • Roberts算子

葵花宝典
差分在边缘检測究竟有什么用呢?先看以下的图片
作为人,我们能够非常easy发现图中红圈有边界,边界处肯定是非常明显,变化陡峭的,在数学中,什么能够表示变化的快慢,自然就是导数,微分了。

想像有例如以下的一维图片。
红圈处变化最陡峭,再看导数图


红圈在最高值,也就是导数能够非常好表示边缘,由于变化非常剧烈


图像中的Sobel算子
  1. 是离散差分算子.
  2. 结合了高斯滤波.

是原始图像:

  1. 我们计算水平和竖直方向的梯度:

    1. 水平方向: Gx是我们Kernel size为3的水平sober算子,与I作卷积

    2. 竖直方向:Gy是我们Kernel size为3的水平sober算子,与I作卷积

  2. 对每一个点,再计算以下的值,得到方向无关梯度

    有时候也能够这样计算:



初识API
C++: void Sobel(InputArray src,
OutputArray dst, int ddepth, int dx, int dy, int ksize=3, double scale=1, double delta=0, intborderType=BORDER_DEFAULT )
 
  • src – 输入.
  • dst – 输出
  • ddepth –
    output image depth; the following combinations of src.depth() and ddepth are
    supported:
    • src.depth() = CV_8Uddepth =
      -1/CV_16S/CV_32F/CV_64F
    • src.depth() = CV_16U/CV_16Sddepth =
      -1/CV_32F/CV_64F
    • src.depth() = CV_32Fddepth =
      -1/CV_32F/CV_64F
    • src.depth() = CV_64Fddepth =
      -1/CV_64F

    when ddepth=-1, the destination image will have the same depth as the source; in the case of
    8-bit input images it will result in truncated derivatives.这里要特别注意了,我们的depth不能为-1,由于我们的输入是uchar8类型的,而算出来的值可能>255也可能 <0 ,都会被截断,CV_16S是推荐的

  • xorder – order of the derivative x.
  • yorder – order of the derivative y.
  • ksize – sobel核大小,必须为1, 3, 5, or 7.
  • scale – 扩大系数
  • delta – 附加系数
  • borderType – 边界类型

计算的时候,利用了可分离的滤波进行加速(Ksize=1的时候,用了1*3和 3*1的算子,无法加速)

当Ksize = 3,Sobel採用的算子会不准确,因此还有特殊的值ksize = CV_SCHARR(-1) 相当于使用  Scharr
filter 比 Sobel算子能获得更准确的结果.
Scharr 算子例如以下


C++: void Scharr(InputArray src,
OutputArray dst, int ddepth, int dx, int dy, double scale=1, double delta=0, int borderType=BORDER_DEFAULT )
 
  • src – input image.
  • dst – output image of the same size and the same number of channels as src.
  • ddepth – output image depth (see Sobel() for
    the list of supported combination of src.depth() and ddepth).
  • dx – order of the derivative x.
  • dy – order of the derivative y.
  • scale – optional scale factor for the computed derivative values; by default, no scaling is applied (see getDerivKernels() for
    details).
  • delta – optional delta value that is added to the results prior to storing them in dst.
  • borderType – pixel extrapolation method (see borderInterpolate() for
    details).

The function computes the first x- or y- spatial image derivative using the Scharr operator. The call

is equivalent to

用法一样~~



荷枪实弹
  1. #include "opencv2/imgproc/imgproc.hpp"
  2. #include "opencv2/highgui/highgui.hpp"
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5.  
  6. using namespace cv;
  7.  
  8. int main( int, char** argv )
  9. {
  10.  
  11. Mat src, src_gray;
  12. Mat grad;
  13. const char* window_name = "Sobel Demo - Simple Edge Detector";
  14.  
  15. //由于以Sobel方式求完导数后会有负值,还有会大于255的值而你建的Sobel的图像是 CV_8U,也就是8位无符号数,所以Sobel建立的图像位数不够,要16位有符号的,也就是 CV_16S
  16. int ddepth = CV_16S;
  17. src = imread( argv[1] );
  18. if( !src.data )
  19. { return -1; }
  20.  
  21. GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT );
  22. cvtColor( src, src_gray, CV_RGB2GRAY );
  23.  
  24. namedWindow( window_name, CV_WINDOW_AUTOSIZE );
  25.  
  26. // Generate grad_x and grad_y
  27. Mat grad_x, grad_y;
  28. Mat abs_grad_x, abs_grad_y;
  29.  
  30. // Gradient X
  31. //Scharr( src_gray, grad_x, ddepth, 1, 0);
  32. Sobel( src_gray, grad_x, ddepth, 1, 0, 3);
  33. convertScaleAbs( grad_x, abs_grad_x );
  34.  
  35. // Gradient Y
  36. //Scharr( src_gray, grad_y, ddepth, 0, 1);
  37. Sobel( src_gray, grad_y, ddepth, 0, 1, 3);
  38. convertScaleAbs( grad_y, abs_grad_y );
  39.  
  40. // Total Gradient (approximate)
  41. addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );
  42.  
  43. imshow( window_name, grad );
  44.  
  45. waitKey(0);
  46.  
  47. return 0;
  48. }

效果图:





举一反三
该算子与Sobel算子类似,仅仅是权值有所变化,但两者实现起来功能还是有差距的,据经验得知Sobel要比Prewitt更能准确检測图像边缘。

Robert算子是一种梯度算子,它用交叉的差分表示梯度,是一种利用局部差分算子寻找边缘的算子,对具有陡峭的低噪声的图像效果最好:

以下我们来用prewitt算子作边缘检測,还记得我们曾经在http://blog.csdn.net/abcd1992719g/article/details/24625805用过的自己定义滤波不,以下我们又要用上了。
  1. #include "opencv2/highgui/highgui.hpp"
  2. #include "opencv2/imgproc/imgproc.hpp"
  3. using namespace cv;
  4.  
  5. int main( int, char** argv )
  6. {
  7. Mat src,gray,Kernelx,Kernely;
  8.  
  9. src = imread( argv[1] );
  10. cvtColor( src, gray, CV_RGB2GRAY );
  11. namedWindow("srcImage", 1);
  12. namedWindow("dstImage", 1);
  13.  
  14. Kernelx = (Mat_<double>(3,3) << 1, 1, 1, 0, 0, 0, -1, -1, -1);
  15. Kernely = (Mat_<double>(3,3) << -1, 0, 1, -1, 0, 1, -1, 0, 1);
  16.  
  17. Mat grad_x, grad_y;
  18. Mat abs_grad_x, abs_grad_y, grad;
  19.  
  20. filter2D(gray, grad_x, CV_16S , Kernelx, Point(-1,-1));
  21. filter2D(gray, grad_y, CV_16S , Kernely, Point(-1,-1));
  22. convertScaleAbs( grad_x, abs_grad_x );
  23. convertScaleAbs( grad_y, abs_grad_y );
  24.  
  25. addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );
  26. imshow("dstImage", grad);
  27.  
  28. waitKey();
  29. return 0;
  30. }

效果图:







计算机视觉讨论群162501053
转载请注明:http://blog.csdn.net/abcd1992719g


OpenCV2马拉松第14圈——边缘检測(Sobel,prewitt,roberts)的更多相关文章

  1. OpenCV2马拉松第15圈——边缘检測(Laplace算子,LOG算子)

    收入囊中 拉普拉斯算子 LOG算子(高斯拉普拉斯算子) OpenCV Laplacian函数 构建自己的拉普拉斯算子 利用拉普拉斯算子进行图像的锐化 葵花宝典 在OpenCV2马拉松第14圈--边缘检 ...

  2. OpenCV2马拉松第17圈——边缘检測(Canny边缘检測)

    计算机视觉讨论群162501053 转载请注明:http://blog.csdn.net/abcd1992719g 收入囊中 利用OpenCV Canny函数进行边缘检測 掌握Canny算法基本理论 ...

  3. openCV2马拉松第19圈——Harris角点检測(自己实现)

    计算机视觉讨论群162501053 转载请注明:http://blog.csdn.net/abcd1992719g/article/details/26824529 收入囊中 使用OpenCV的con ...

  4. 【OpenCV新手教程之十二】OpenCV边缘检測:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/25560901 作者:毛星云(浅墨) ...

  5. 图像边缘检測--OpenCV之cvCanny函数

    图像边缘检測--OpenCV之cvCanny函数 分类: C/C++ void cvCanny( const CvArr* image, CvArr* edges, double threshold1 ...

  6. OpenCV图像处理篇之边缘检測算子

    3种边缘检測算子 灰度或结构等信息的突变位置是图像的边缘,图像的边缘有幅度和方向属性.沿边缘方向像素变化缓慢,垂直边缘方向像素变化剧烈.因此,边缘上的变化能通过梯度计算出来. 一阶导数的梯度算子 对于 ...

  7. Canny边缘检測算法原理及其VC实现具体解释(一)

    图象的边缘是指图象局部区域亮度变化显著的部分,该区域的灰度剖面一般能够看作是一个阶跃,既从一个灰度值在非常小的缓冲区域内急剧变化到还有一个灰度相差较大的灰度值.图象的边缘部分集中了图象的大部分信息,图 ...

  8. Python图像处理(8):边缘检測

    快乐虾 http://blog.csdn.net/lights_joy/ 欢迎转载,但请保留作者信息 此前已经得到了单个区域植株图像,接下来似乎应该尝试对这些区域进行分类识别.通过外形和叶脉进行植物种 ...

  9. 图像处理之Canny边缘检測

    图像处理之Canny 边缘检測 一:历史 Canny边缘检測算法是1986年有John F. Canny开发出来一种基于图像梯度计算的边缘 检測算法,同一时候Canny本人对计算图像边缘提取学科的发展 ...

随机推荐

  1. Block内的强引用

    众所周知,当某个对象持有着一个Block的时候,如果在Block内部使用强引用反过来持有这个对象,就会导致引用循环.为了避免引用循环,可以使用__weak修饰符,苹果的官方文档在用代码演示__weak ...

  2. 谷歌推出情境感知API

    在 Google I/O 2016 大会上,我们宣布推出新的 Google Awareness API,让您的应用可以利用快照和围栏智能应对用户情境,并且仅需占用极少量的系统资源. 所有开发者均可以通 ...

  3. javascript切换效果

    html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta ...

  4. 关于EventHandler的使用

    也就是委托和事件的使用.使用过,但了解的不够深入,现在逐渐来填以前留下的坑吧. EventHandler, EventHandler<TEventArg> 是.net Framework内 ...

  5. c#中传递参数前加out

    首先:两者都是按地址传递的,使用后都将改变原来参数的数值. 其次: rel 可以把参数的数值传递进函数,但是 out 是要把参数清空,就是说你无法把一个数值 从 out 传递进去的, out 进去后, ...

  6. 注册界面的优化之ActionBar组件的应用之(一)ActionBar组件的布局实现

    开发步骤:  在res下menu文件夹中创建一个actionbar_menu_register.xml菜单资源文件  在资源文件中添加标签设置一个或多个ActionBar功能选项 //action ...

  7. hdu120118岁生日

    Problem Description Gardon的18岁生日就要到了,他当然很开心,可是他突然想到一个问题,是不是每个人从出生开始,到达18岁生日时所经过的天数都是一样的呢?似乎并不全都是这样,所 ...

  8. git rm

    git rm可以执行删除的条件(前提是要被删除的文件还没有从workspace tree中移除) git rm可以执行删除的条件:被删除文件在index当中的blob内容必须与HEAD commit指 ...

  9. httpd-vhosts.conf的配置

    <VirtualHost *:80> DocumentRoot "D:\product\web\Public" ServerName demo.web.com Dire ...

  10. 解决: AGPBI: {"kind":"error","text":"indicate that it is *not* an inner class.","sources":[{}]}

    关于Gradle Console输出类似这样错误信息: AGPBI: {"kind":"error","text":"indica ...