本文转于:https://blog.csdn.net/u014020344/article/details/50196635 若用侵权 请联系删除 ?

在这一讲中我们来学习一下opencv中最基本的边缘检测的知识,首先我们来介绍一下图像梯度

1.图像梯度

可以把图像看成二维离散函数,图像梯度其实就是这个二维离散函数的求导:
图像梯度:

梯度算子 Gradient operators

函数f(x,y)在(x,y)处的梯度为一个向量:

计算这个向量的大小为:

近似为:

梯度的方向角为:

可能上面的数学表达式大家觉得还是过于抽象,那么我们将图片看成是二维的离散函数,那么图像的梯度其实就是这个二维离散函数的求导(偏导数)

图像梯度: G(x,y) = dx i + dy j;
dx(i,j) = I(i+1,j) - I(i,j);
dy(i,j) = I(i,j+1) - I(i,j);
其中,I是图像像素的值(如:RGB值),(i,j)为像素的坐标。
图像梯度一般也可以用中值差分:
dx(i,j) = [I(i+1,j) - I(i-1,j)]/2;
dy(i,j) = [I(i,j+1) - I(i,j-1)]/2;

图像边缘一般都是通过对图像进行梯度运算来实现的。

图像梯度的最重要性质是,梯度的方向在图像灰度最大变化率上,它恰好可以反映出图像边缘上的灰度变化 
上面说的是简单的梯度定义,其实还有更多更复杂的梯度公式。

2.边缘检测

关于边缘的细节知识,请参考博主 http://blog.csdn.net/xiaowei_cqu/article/details/7829481

下面让我们来看一下边缘检测中常用的一些算子:

sobel算子边缘检测算法

索贝尔算子(Sobel operator)主要用作边缘检测,在技术上,它是一离散性差分算子,用来运算图像亮度函数的灰度之近似值。在图像的任何一点使用此算子,将会产生对应的灰度矢量或是其法矢量

Sobel卷积因子为:

具体计算如下:

Gx = (-1)*f(x-1, y-1) + 0*f(x,y-1) + 1*f(x+1,y-1)

+(-2)*f(x-1,y) + 0*f(x,y)+2*f(x+1,y)

+(-1)*f(x-1,y+1) + 0*f(x,y+1) + 1*f(x+1,y+1)

= [f(x+1,y-1)+2*f(x+1,y)+f(x+1,y+1)]-[f(x-1,y-1)+2*f(x-1,y)+f(x-1,y+1)]

Gy =1* f(x-1, y-1) + 2*f(x,y-1)+ 1*f(x+1,y-1)

+0*f(x-1,y) 0*f(x,y) + 0*f(x+1,y)

+(-1)*f(x-1,y+1) + (-2)*f(x,y+1) + (-1)*f(x+1, y+1)

= [f(x-1,y-1) + 2f(x,y-1) + f(x+1,y-1)]-[f(x-1, y+1) + 2*f(x,y+1)+f(x+1,y+1)]

其中f(a,b), 表示图像(a,b)点的灰度值;

Sobel算子根据像素点上下、左右邻点灰度加权差,在边缘处达到极值这一现象检测边缘。对噪声具有平滑作用,提供较为精确的边缘方向信息,边缘定位精度不够高。当对精度要求不是很高时,是一种较为常用的边缘检测方法。

其实在边缘检测中还会用到很多算子,如普利维特算子(Prewitt operate);罗伯茨交叉边缘检测(Roberts Cross operator);拉普拉斯算子等等。

2.opencv中Sobel算子实现边缘检测效果图

先上效果图:

当然,opencv中其实上面的代码完全可以用

void cvSobel( const CvArr* src, CvArr* dst, int xorder, int yorder, int aperture_size=3 );

这个函数来代替,相应的参数大家可以去百度,在这就不一一介绍了,本文主要针对sobel算子的检测原理来进行说明。

代码如下

  1. #include "cv.h"
  2. #include "highgui.h"
  3. #include "math.h"
  4. #include "stdio.h"
  5. #include "malloc.h"
  6. IplImage *image; //声明IplImage指针
  7. int height, width;
  8. CvScalar s;
  9. int sobel_y[9] = { 1, 2, 1, 0, 0, 0, -1, -2, -1 }; //y方向sobel算子
  10. int sobel_x[9] = { 1, 0, -1, 2, 0, -2, 1, 0, -1 }; //x方向sobel算子
  11. void sobel()
  12. {
  13. int i, j, k;
  14. int grayx = 0, grayy = 0, gray;
  15. int *data;
  16. int a[9];
  17. data = (int *)malloc(height*width*sizeof(int));
  18. for (i = 0; i<height; i++)
  19. {
  20. for (j = 0; j<width; j++)
  21. {
  22. s = cvGet2D(image, i, j);
  23. gray = (int)s.val[0];
  24. data[i*width + j] = gray;
  25. }
  26. }
  27. for (i = 1; i<height - 1; i++)
  28. {
  29. for (j = 1; j<width - 1; j++)
  30. {
  31. grayx = 0;
  32. grayy = 0;
  33. s = cvGet2D(image, i, j);
  34. a[0] = data[width*(i - 1) + j - 1];
  35. a[1] = data[width*(i - 1) + j];
  36. a[2] = data[width*(i - 1) + j + 1];
  37. a[3] = data[width*i + j - 1];
  38. a[4] = data[width*i + j];
  39. a[5] = data[width*i + j + 1];
  40. a[6] = data[width*(i + 1) + j - 1];
  41. a[7] = data[width*(i + 1) + j];
  42. a[8] = data[width*(i + 1) + j + 1];
  43. for (k = 0; k<9; k++)
  44. grayy += a[k] * sobel_y[k];
  45. for (k = 0; k<9; k++)
  46. grayx += a[k] * sobel_x[k];
  47. s.val[0] = (abs(grayx) + abs(grayy));//此处需要取绝对值
  48. cvSet2D(image, i, j, s);
  49. }
  50. }
  51. free(data);
  52. }
  53. int main(int argc, char** argv)
  54. {
  55. image = cvLoadImage("image1.jpg", 0);
  56. IplImage* image1 = cvLoadImage("image1.jpg", 1);
  57. height = image->height;
  58. width = image->width;
  59. sobel();
  60. cvNamedWindow("Image", 1);//创建窗口
  61. cvNamedWindow("Sobel", 1);//创建窗口
  62. cvShowImage("Image", image1);//显示图像
  63. cvShowImage("Sobel", image);//显示图像
  64. cvWaitKey(0); //等待按键
  65. cvDestroyWindow("Image");//销毁窗口
  66. cvReleaseImage(&image); //释放图像
  67. return 0;
  68. }

参考文章:

http://blog.csdn.net/xiaowei_cqu/article/details/7829481

梯度,sobel算子的理解相关推荐

  1. 11-图像梯度-Sobel算子

    图像梯度是指图像某像素在x和y两个方向上的变化率(与相邻像素比较),是一个二维向量,由2个分量组成,X轴的变化.Y轴的变化 . 其中X轴的变化是指当前像素右侧(X加1)的像素值减去当前像素左侧(X减1 ...

  2. Sobel算子的理解

    sobel算子主要用于获得数字图像的一阶梯度,常见的应用和物理意义是边缘检测. 原理 算子使用两个33的矩阵(图1)算子使用两个33的矩阵(图1)去和原始图片作卷积,分别得到横向G(x)和纵向G(y) ...

  3. OpenCV--033_2: 图像梯度--Sobel算子

    索贝尔算子(Sobel operator) 主要用作边缘检测,在技术上,它是一离散性差分算子,用来运算图像亮度函数的灰度之近似值.在图像的任何一点使用此算子,将会产生对应的灰度矢量或是其法矢量. So ...

  4. OpenCV-Python图像梯度 Sobel算子

    图像的梯度计算的是图像变化的速度,对于边缘部分呢灰度值变换大,梯度值也大,相反则灰度值变化小,梯度值小 Sobel算子是一种离散的微分算子,该算子结合了高斯平滑处理和微分求导运算. 该算子利用局部差寻 ...

  5. OpenCV-图像梯度 sobel算子

    # 第一步:载入原始图片# 第二步:使用cv2.Sobel(src, cv2.CV_64F, 1, 0, ksize=3) 对x轴方向进行sobel算子相乘操作# 第三步:由于会出现负值的情况,因此使 ...

  6. sobel算子 拉普拉斯算子以及散度与梯度的概念

    在ECBSR论文的代码研究中,我发现关于ECBSR提出的多分支重参数化模型中,代码用到了sobel算子与laplace算子,很难判断这两个算子是为了论文的创新点还是真的有用,这块只能等待后续的对比实验 ...

  7. 图像的常规边缘检测(梯度算子、Roberts算子和Sobel算子)之c++实现(qt + 不调包)

    1.基本原理 边缘检测一般是利用微分等方法,通过对灰度跃变的分析寻找图像上区域边缘的技术.今天的猪脚是梯度算子和Roberts算子. 1.梯度算子是怎么来的? 答:图像是一个二维集合,在(x, y)处 ...

  8. 学习sobel算子对图像求导自我理解

    sobel算子,其实也就是近似把对函数进行偏导数计算,转化为适合图像计算的矩阵, 把整个图像当做为二元函数,然后分别对二元(x和y)求偏导数. 偏导数其实高数考试里面的形象解释不多,个人就当导数理解, ...

  9. 计算机视觉开源库OpenCV梯度之Sobel算子

    Sobel算子是像素图像边缘检测中最重要的算子之一,在机器学习.数字媒体.计算机视觉等信息科技领域起着举足轻重的作用.在技术上,它是一个离散的一阶差分算子,用来计算图像亮度函数的一阶梯度之近似值.在图 ...

最新文章

  1. 到成都去是联想的必然选择
  2. pandas为dataframe所有的列名称名添加前缀(add_prefix)
  3. 20151217:Web之Repeater使用:添加
  4. iis 重新安装后 重新注册asp.net
  5. 中石油训练赛 - sciorz画画(区间dp)
  6. 在 Asp.Net Core WebAPI 中防御跨站请求伪造攻击
  7. 工作403-修改input里面的文本框值
  8. 【bzoj2132】圈地计划 网络流最小割
  9. [转]关于凸优化的一些简单概念
  10. Windows workflow foundation之旅(三)——指南2(创建状态机工作流)(上)
  11. Never Call Virtual Functions during Constructio...
  12. HCNA培训常见问题001-HCNA AI学习什么内容?
  13. GPIO推挽输出和开漏输出模式区别详解
  14. MATLAB安装后出现问题:MTALAB2021安装后闪退打不开
  15. KWS_关键词命名+识别率和误识别率
  16. SpringBoot 就这一篇全搞定
  17. 我最近在看什么——《蛤蟆先生去看心理医生》
  18. 实验一-Bomblab(炸弹实验)
  19. 利用echarts做图表统计
  20. 软件测试需要学什么?测试小白入门必看!

热门文章

  1. python3的urllib3和requests
  2. Excel每隔10行取得一个数字
  3. QT实现的自定义按键精灵
  4. 判断质数和合数python代码_质数,非质数之Python
  5. 在 Linux中安装中文输入法
  6. Git 中 git restore 的使用
  7. Calendar计算两个日期之间的天数和周数
  8. python罗马数字转换阿拉伯数字_Python将阿拉伯数字转换为罗马数字的方法
  9. pyecharts去除小圆圈
  10. 结构体指针和结构体指针变量的区别