【译】Sobel 算子文档

来源:互联网 发布:淘宝cad画图接活群 编辑:程序博客网 时间:2024/06/05 20:54

参考网址:https://docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/sobel_derivatives/sobel_derivatives.html

一.目标
在这篇指南中你将学会如何:

  • 使用OpenCV 中的Sobel 算子计算图像中的导数。
  • 使用OpenCV 中的Scharr 算子计算一个3*3大小的核的一个更精确的导数。

二.理论
说明:下面的解释说明来自由Bradski 和Kaehler写的《Learning OpenCV》

为什么计算图像中的衍生物的微积分十分重要?让我们想象如果我们想要检测到图像中出现的边缘,如下图:
这里写图片描述

你会发现在边缘处,像素点亮度出现显著的变化。使用导数能够很好的展现变化。梯度上的变化表现出图像中的较大的变化。

为了图示的更加清晰,假设我们有一个一维的图像,下面图表中亮度值的“跳跃”表现出边缘部分:
这里写图片描述

如果我们求第一次导数(事实上,图中表现为最大点),边缘部分的“跳跃”更能够表现出来。
这里写图片描述

所以,根据上述的解释说明,我们可以推导出一个在图像中检测边缘的方法,即通过确定一个梯度值大于领域中其他像素点(推广思路可改用阈值)的点的位置并表现在图像中。

更多的细节解释,可以参考Bradski 和Kaehler 的《Learning OpenCV》

Sobel 算子

  1. Sobel 算子是一个具体的差异化的算子。它用于计算图像中亮度梯度的估计值。
  2. Sobel 算子是将差异化和高斯滤波合并起来

处理
假设待处理的图像为I:

  1. 我们计算两个导数:
    a.水平变化:通过计算I 与核Gx的卷积,其中Gx是一个具有奇数边长的核。比如对于一个3*3的核,Gx可以像下面这样计算:
    Gx = 121000+1+2+1 * I
    b.竖直变化:通过计算I 与核Gx的卷积,其中Gx是一个具有奇数边长的核。比如对于一个3*3的核,Gx可以像下面这样计算:
    Gy = 10+120+210+1 * I
  2. 在图像中的每个像素点上,我们通过使用下述公式计算结果来获取该像素点的梯度的估计值:
    G = (Gx)2+(Gy)2

尽管有时会使用下面的公式:
G = |Gx| + |Gy|

注意:当核的尺寸为3*3时,上面提到的Sobel 算子将会产生很明显的误差(毕竟,Sobel 算子是一种对导数的估计)。OpenCV 强调可以用Scharr 函数来处理使用3*3 的核产生的误差。这种方法和标准的Sobel 算子要快,同时更加准确,它是使用如下的形式的核:
Gx = 3103000+3+10+3
Gy = 30+3100+1030+3

你可以在OpenCV 参考中找到更多有关Scharr 的相关信息。并且,在下面相同的代码中,你讲发现不仅有Sobel 算子还有注释过的Scharr 算子。取消注释将展现这个方法的工作原理。

代码:

  1. 这段代码用来干什么?
    使用Sobel 算子并且生成一张图作为输出,输出的图像将在深色的背景上用亮色表示找到的边缘。
  2. 下面展示指导代码:
#include "opencv2/imgproc/imgproc.hpp"#include "opencv2/highgui/highgui.hpp"#include <stdlib.h>#include <stdio.h>using namespace cv;/** @function main */int main( int argc, char** argv ){  Mat src, src_gray;  Mat grad;  char* window_name = "Sobel Demo - Simple Edge Detector";  int scale = 1;  int delta = 0;  int ddepth = CV_16S;  int c;  /// Load an image  src = imread( argv[1] );  if( !src.data )  { return -1; }  GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT );  /// Convert it to gray  cvtColor( src, src_gray, CV_BGR2GRAY );  /// Create window  namedWindow( window_name, CV_WINDOW_AUTOSIZE );  /// Generate grad_x and grad_y  Mat grad_x, grad_y;  Mat abs_grad_x, abs_grad_y;  /// Gradient X  //Scharr( src_gray, grad_x, ddepth, 1, 0, scale, delta, BORDER_DEFAULT );  Sobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT );  convertScaleAbs( grad_x, abs_grad_x );  /// Gradient Y  //Scharr( src_gray, grad_y, ddepth, 0, 1, scale, delta, BORDER_DEFAULT );  Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );  convertScaleAbs( grad_y, abs_grad_y );  /// Total Gradient (approximate)  addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );  imshow( window_name, grad );  waitKey(0);  return 0;  }

注释:

  1. 首先我们声明我们将要使用的变量:
Mat src, src_gray;Mat grad;char* window_name = "Sobel Demo - Simple Edge Detector";int scale = 1;int delta = 0;int ddepth = CV_16S;
  1. 然后加载我们的源图像:
src = imread( argv[1] );if( !src.data ){ return -1; }
  1. 第一步,我们使用高斯滤波过滤噪点(核为3*3):
GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT );
  1. 将过滤后的图像转换成灰度图:
cvtColor( src, src_gray, CV_BGR2GRAY );
  1. 下一步,我们在x 和y 方向上计算导数,我们按照下面的方式使用Sobel 算子:
Mat grad_x, grad_y;Mat abs_grad_x, abs_grad_y;/// Gradient XSobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT );/// Gradient YSobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );

函数中的参数:

  • src_gray :在我们的例子中是输入的图像,这里图像格式为CV_8U
  • grad_x | grad_y:输出的图像
  • ddepth :输出的图像的深度,我们将格式设置为CV_16S防止溢出。
  • x_order :x轴方向上的导数序列
  • y_order :y轴方向上的导数序列
  • scale ,delta 和BORDER_DEFAULT:使用默认值

注意到我们使用xorder=1yorder=0我们在y轴方向上做类似操作。

  1. 将部分得到的结果重新转换为CV_8U
convertScaleAbs( grad_x, abs_grad_x );convertScaleAbs( grad_y, abs_grad_y );
  1. 最后,我们通过两个方向的梯度估算每个像素点的梯度值(需要指出的是,这并不是最好的计算结果,但是的确符合我们的要求)
addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );
  1. 最后我们展示出处理后的结果:
imshow( window_name, grad );

结果:
下面是我们通过基本的检测得到的结果图:
这里写图片描述

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 车子被朋友撞了怎么办 电车被交警扣了怎么办 e照扣了12分怎么办 驾驶证被扣33分怎么办 a2驾驶员扣33分怎么办 驾驶证被扣48分怎么办 驾照扣了33分怎么办 车辆被扣36分怎么办 车被朋友借走了怎么办 在中国终身禁驾怎么办 c驾驶证忘年审了怎么办 驾驶证脱审1年多怎么办 驾驶证脱审四个月怎么办 驾照b2过期没审怎么办 a照驾照过期没审怎么办 驾照扣60多分怎么办 无证违章被扣分怎么办 变味的牛奶喝了怎么办 孩子喝了坏牛奶怎么办 孕妇喝了坏牛奶怎么办 驾照过期五年了怎么办 科目一没过之后怎么办? 重庆科目一没过怎么办 科三过了没签字怎么办 驾照过期几天撞死人怎么办 办理过期身份时出错了怎么办 新加坡半年临时驾照过期后怎么办 北京怎么办残摩行驶证 报考驾照三年到期了怎么办 车辆违章扣3分怎么办 驾照过期忘审了怎么办 外省港澳证办了居住证怎么办 电动车交警罚单丢了怎么办 在外地开车违章扣分怎么办 郑州车在外地扣分违章怎么办 电工证掉了应该怎么办 毕业回国美国驾照过期了怎么办 a2驾驶证4年没交体检报告怎么办 中国驾照在美国丢了怎么办 拿了驾照不敢开车怎么办 刚拿驾照不敢上路怎么办