您的位置:首页 > 编程语言 > C语言/C++

OpenCV教程 之 边缘检测函数:Canny、Sobel、Scharr(C++)

2017-11-18 21:01 836 查看
边缘检测是数字图像处理领域非常重要与基础的操作,这里简单介绍OpenCV里的Canny检测算子、sobel检测算子、scharr滤波器的基本应用

一、Canny算子

Canny边缘检测算子是John F.Canny于1986年开发出来的一个多级边缘检测算法。更为重要的是,Canny创立了边缘检测计算理论,解释了这项技术是如何工作的。Canny边缘检测算法以Canny的名字命名,被很多人推崇为当今最优的边缘检测算法

在OpenCV中,Canny函数利用Canny算子来进行图像的边缘检测操作,我们先来看看它的函数原型

void Canny(InputArray image,Output edges,double threshold1,double threshold2,int apertureSize= 3,bool L2gradient = false)

@第一个参数,InputArray类型的image,输入图像,即原图像,填Mat类型的对象即可,且需为单通道8位图像
@第二个参数,OutputArray类型的edges,输出的边缘图,需要和源图片有一样的尺寸和类型
@第三个参数,double类型的threshold1,第一个滞后性阈值
@第四个参数,double类型的threshold2,第二个滞后性阈值
@第五个参数,int类型的apertureSize,表示应用Sobel算子的孔径大小,其有默认值3
@第六个参数,bool类型的L2gradient,一个计算图像梯度幅值的标识,有默认值false


举个栗子:

“1.jpg”如下,是一匹小马,我们接下来的程序都以这个为源图片



Mat src = imread("1.jpg");
Canny(src,src,3,9,3);
imshow("【效果图】Canny边缘检测",src);


效果图如下:



二、Sobel算子

Sobel算子是一个主要用于边缘检测的离散微分算子。它结合了高斯平滑和微分求导,用来计算图像灰度函数的近似梯度

在OpenCV中,Sobel函数使用扩展的Sobel算子来计算一阶、二阶、三阶或者混合图像的差分,我们来看一下它的函数原型

void Sobel(InputArray src,OutputArray dst,int ddepth,int dx,int dy,int ksize = 3,double scale = 1,double delta = 0,int borderType = BORDER_DEFAULT);

@第一个参数,InputArray类型的src,为输入图像,填Mat类型即可
@第二个参数,OutputArray类型的dst,基本目标图像,函数的输出参数,需要和源图片有一样的尺寸和类型
@第三个参数,int类型的ddepth,输出图像的深度
@第四个参数,int类型的dx,x方向上的差分阶数
@第五个参数,int类型的dy,y方向上的差分阶数
@第六个参数,int类型的ksize,有默认值3,表示Sobel核的大小,可以在1、3、5、7中选取一个
@第七个参数,double类型的scale,计算导数值时可以选择的缩放因子,默认值是1,表示默认情况下是没有缩放应用的
@第八个参数,double类型的delta,表示在结果存入目标图之前可选的delta值,默认为0
@第九个参数,int类型的borderType,边界模式,有默认值BORDER_DEFAULT


举个栗子

int main()
{
//创建grad_x和grad_y矩阵
Mat grad_x,grad_y;
Mat abs_grad_x,abs_grad_y,dst;

//载入原始图
Mat src = imread("1.jpg")

//求x方向梯度
Sobel(src,grad_x,CV_16S,1,0,3,1,1,BORDER_DEFAULT);
convertScaleAbs(grad_x,abs_grad_x);

//求y方向梯度
Sobel(src,grad_y,CV_16S,0,1,3,1,1,BORDER_DEFAULT);
convertScaleAbs(grad_y,abs_grad_y);

//合并梯度
addweighted(abs_grad_x,0.5,abs_grad_y,0.5,0,dst);
inshow("【效果图】Sobel边缘检测",dst);

waitKey(0);
return(0);
}


效果图如下:



三、Scharr滤波器

我们一般直接称Scharr为滤波器,而不是算子。使用Scharr滤波器计算x或y方向的图像差分,其实它的参数变量和Sobel基本上是一样的,除了没有Ksize核的大小

void Schurr(InputArray src,outputArray dst,int ddepth,int dx,int dy,double scale = 1,double delta = 0,intborderType = BORDER_DEFAULT)
@第一个参数,InputArray类型的src,为输入图像,填Mat类型即可
@第二个参数,OutputArray类型的dst,即目标图像,函数的输出参数,需要和源图像有一样的尺寸和类型
@第三个参数,int类型的ddpeth,输出图像的深度
@第四个参数,int类型的dx,x方向上的差分阶数
@第五个参数,int类型的dy,y方向上的差分阶数
@第六个参数,double类型的scale,计算导数值时可选的缩放因子,默认为1
@第七个参数,double类型的delta,表示在结果存入目标图之前可选的delta值,有默认值0
@第八个参数,int类型的borderType,边界模式,有默认值BORDER_DEFAULT


举个栗子

int main()
{
//创建grad_x和grad_y矩阵
Mat grad_x,grad_y;
Mat abs_grad_x,abs_grad_y,dst;

//载入原始图
Mat src = imread("1.jpg")

//求x方向梯度
Scharr(src,grad_x,CV_16S,1,0,1,0,BORDER_DEFAULT);
convertScaleAbs(grad_x,abs_grad_x);

//求y方向梯度
Scharr(src,grad_y,CV_16S,0,1,1,0,BORDER
ba7a
_DEFAULT);
convertScaleAbs(grad_y,abs_grad_y);

//合并梯度
addweighted(abs_grad_x,0.5,abs_grad_y,0.5,0,dst);
inshow("【效果图】Scharr边缘检测",dst);

waitKey(0);
return(0);
}


效果图如下:



综合实例

此处为上文中所讲述的OpenCV中的三种边缘检测算法应用实例:

https://github.com/LiangjunFeng/Implement-OpenCV/blob/master/4.EdgeDetected.cpp
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐