OpenCV学习(48)

图像变换(2):基于OpenCV的边缘检测

三,sobel算子;

1. sobel算子的基本概念

2. sobel算子的计算过程

3.使用Sobel算子:Sobel()函数

 4.示例程序:Sobel算子的使用

三,sobel算子

1. sobel算子的基本概念

      Sobel 算子是一个主要用于边缘检测的离散微分算子( discrete differentiationoperator)。它结合了高斯平滑和微分求导,用来计算图像灰度函数的近似梯度。在图像的任何一点使用此算子,都将会产生对应的梯度矢量或是其法矢量。

2. sobel算子的计算过程

   我们假设被作用图像为Ⅰ然后进行如下操作。

   (1)分别在x和y两个方向求导。
①水平变化:将Ⅰ与一个奇数大小的内核G进行卷积。比如,当内核大小为3时,Gx的计算结果为:

②垂直变化:将:I与一个奇数大小的内核进行卷积。比如,当内核大小为3时,计算结果为:

(2)在图像的每一点,结合以上两个结果求出近似梯度:

3.使用Sobel算子:Sobel()函数

Sobel 函数使用扩展的Sobel算子,来计算一阶、二阶、三阶或混合图像差分。

     (1)第一个参数,InputArray类型的src,为输入图像,填Mat类型即可。

     (2)第二个参数,OutputArray类型的dst,即目标图像,函数的输出参数,需要和源图片有一样的尺寸和类型。
     (3)第三个参数,int类型的ddepth,输出图像的深度,支持如下src.depth()和 ddepth的组合:
若src.depth()= cV_8U,取 ddepth =-1/CV_16S/CV_32F/CV_64F·若src.depth() = CV_16U/CV_16S,取 ddepth =-1/CV_32F/CV_64F●若src.depth(= CV_32F,取 ddepth=-1/CV_32F/CV_64F
若src.depth( = cV_64F,取ddepth = -1/CV_64F
     (4)第四个参数,int类型dx,x方向上的差分阶数。

     (5)第五个参数,int类型dy,y方向上的差分阶数。
     (6)第六个参数,int类型ksize,有默认值3,表示Sobel核的大小;必须取1、3、5或7。
     (7)第七个参数,double类型的scale,计算导数值时可选的缩放因子,默认值是1,表示默认情况下是没有应用缩放的。可以在文档中查阅 getDerivKernels的相关介绍,来得到这个参数的更多信息。
     (8)第八个参数,double类型的delta,表示在结果存入目标图(第二个参数dst)之前可选的delta值,有默认值0。
     (9)第九个参数,int类型的 borderType,边界模式,默认值为 BORDER_DEFAULT。这个参数可以在官方文档中borderInterpolate处得到更详细的信息。

一般情况下,都是用ksize x ksize内核来计算导数的。然而,有一种特殊情况——当ksize为1时,往往会使用3x1或者1x 3的内核。且这种情况下,并没有进行高斯平滑操作。
一些补充说明如下。
①当内核大小为3时,Sobel 内核可能产生比较明显的误差(毕竟,Sobel算子只是求取了导数的近似值而已)。为解决这一问题,OpenCV提供了Scharr函数,但该函数仅作用于大小为3的内核。该函数的运算与Sobel函数一样快,但结果却更加精确,其内核是这样的:

 因为Sobel算子结合了高斯平滑和分化( differentiation),因此结果会具有更多的抗噪性。大多数情况下,我们使用sobel函数时,取【xorder = 1,yorder =0,ksize = 3】来计算图像X方向的导数,【xorder = 0,yorder = 1,ksize = 3】来计算图像y方向的导数。
计算图像X方向的导数,取【xorder= 1,yorder = 0,ksize = 3】情况对应的内核:

 4.示例程序:Sobel算子的使用

代码:

#include<opencv2/opencv.hpp>
#include <opencv2/core/utils/logger.hpp>
#include<iostream>
using namespace std;
using namespace cv;//包含cv命名空间
int main()
{
	cv::utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);//控制台不在输出日志文件
	//创建grad_x和grad_y矩阵
	Mat grad_x, grad_y;
	Mat abs_grad_x, abs_grad_y,dst;
	//载入原始图
	Mat src = imread("E:/pictures/2.jpg");
	//显示原始图
	imshow("【原始图】sobel边缘检测",src);
	//求X方向梯度
	Sobel(src, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);
	convertScaleAbs(grad_x,abs_grad_x);
	imshow("【效果图】x方向sobel",abs_grad_x);
	//求y方向梯度
	Sobel(src, grad_y, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);
	convertScaleAbs(grad_y, abs_grad_y);
	imshow("【效果图】y方向sobel", abs_grad_y);
	//合并梯度(近似)
	addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst);
	imshow("【效果图】整体方向Sobel", dst);
	waitKey(0);
	return 0;

}

运行结果:








 

 

 

 

 

 

 

 

 

 



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值