基于OpenCv的边缘检测——Laplacian算子、scharr滤波器

Laplacian算子边缘检测效果图

原始图

这里写图片描述

灰度图

这里写图片描述

效果图

这里写图片描述

scharr滤波器边缘检测效果图

原始图

这里写图片描述

X方向

这里写图片描述

Y方向

这里写图片描述

Scharr合并图

这里写图片描述

1、Laplacian算子的简介

Laplacian 算子是n维欧几里德空间中的一个二阶微分算子,定义为梯度grad的散度div。可使用运算模板来运算这定理定律。

如果f是二阶可微的实函数,则f的拉普拉斯算子定义为:
(1) f的拉普拉斯算子也是笛卡儿坐标系中的所有非混合二阶偏导数求和:
(2) 作为一个二阶微分算子,拉普拉斯算子把C函数映射到C函数,对于k ≥ 2。表达式(1)(或(2))定义了一个算子Δ : C(R) → C(R),或更一般地,定义了一个算子Δ : C(Ω) → C(Ω),对于任何开集Ω。
对于阶跃状边缘,导数在边缘点出现零交叉,即边缘点两旁二阶导数取异号。据此,对数字图像{f(i,j)}的每个像素,取它关于x轴方向和y轴方向的二阶差分之和,表示为

这里写图片描述

2、运算模板

函数的拉普拉斯算子也是该函数的黑塞矩阵的迹,可以证明,它具有各向同性,即与坐标轴方向无关,坐标轴旋转后梯度结果不变。如果邻域系统是4 邻域,Laplacian 算子的模板为:

这里写图片描述

如果邻域系统是8 邻域,Laplacian 算子的模板为:

这里写图片描述

前面提过,Laplacian 算子对噪声比较敏感,所以图像一般先经过平滑处理,因为平滑处理也是用模板进行的,所以,通常的分割算法都是把Laplacian 算子和平滑算子结合起来生成一个新的模板。

3、Laplacian算子的代码参考

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;

int On_Laplacian()
{
    //【1】创建矩阵
    Mat gray, dst, a_dst;

    //【2】载入原始图
    Mat src = imread("F://5.png");

    //【3】显示原始图
    imshow("原始图", src);

    //【4】使用高斯滤波消除噪声
    GaussianBlur(src, src, Size(3, 3), 0, 0, BORDER_DEFAULT);

    //【5】转换为灰度图
    cvtColor(src, gray, COLOR_RGB2GRAY);

    imshow("灰度图",gray);

    //【6】使用Laplace函数
    Laplacian(src, dst, CV_16S, 3, 1, 0, BORDER_DEFAULT);

    //【7】计算绝对值,并将结果转换成8位
    convertScaleAbs(dst, a_dst);

    //【8】显示效果图
    imshow("效果图", a_dst);

    return 0;
}

4、scharr滤波器简介

使用Scharr滤波器运算符计算x或y方向的图像差分。其实它的参数变量和Sobel基本上是一样的,除了没有ksize核的大小。

void Scharr(
InputArray src, //源图
 OutputArray dst, //目标图
 int ddepth,//图像深度
 int dx,// x方向上的差分阶数
 int dy,//y方向上的差分阶数
 double scale=1,//缩放因子
 double delta=0,// delta值
 intborderType=BORDER_DEFAULT )// 边界模式

第一个参数,InputArray 类型的src,为输入图像,填Mat类型即可。
第二个参数,OutputArray类型的dst,即目标图像,函数的输出参数,需要和源图片有一样的尺寸和类型。
第三个参数,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
第四个参数,int类型dx,x方向上的差分阶数。
第五个参数,int类型dy,y方向上的差分阶数。
第六个参数,double类型的scale,计算导数值时可选的缩放因子,默认值是1,表示默认情况下是没有应用缩放的。我们可以在文档中查阅getDerivKernels的相关介绍,来得到这个参数的更多信息。
第七个参数,double类型的delta,表示在结果存入目标图(第二个参数dst)之前可选的delta值,有默认值0。
第八个参数, int类型的borderType,我们的老朋友了(万年是最后一个参数),边界模式,默认值为BORDER_DEFAULT。

5、scharr滤波器运用代码

int On_Scharr()
{
    //【1】创建矩阵
    Mat g_x, g_y;
    Mat a_x, a_y,dst;

    //【2】载入原始图
    Mat src = imread("F://5.png");

    //【3】显示原始图
    imshow("Scharr 原始图", src);

    //【4】求X方向的梯度
    Scharr(src, g_x, CV_16S, 1, 0, 1, 0, BORDER_DEFAULT);
    convertScaleAbs(g_x, a_x);
    imshow("x方向", a_x);

    //【5】求Y方向的梯度
    Scharr(src, g_y, CV_16S, 1, 0, 1, 0, BORDER_DEFAULT);
    convertScaleAbs(g_y, a_y);
    imshow("y方向", a_y);

    //【6】合并梯度
    addWeighted(a_x, 0.5, a_y, 0.5, 0, dst);

    //【7】显示效果图
    imshow("scharr合并图", dst);

    return 0;
}

效果图:

这里写图片描述

整个工程代码下载链接:

点我下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值