目录
一、前言
二、算子复习
1、算子
2、Sobel算子
三、Laplance算子
1、讲解
2、API
3、代码展示
继续填坑。
如果想看其他有关于OpenCV学习方法介绍、学习教程、代码实战、常见报错及解决方案等相关内容,可以直接看我的OpenCV分类:
【OpenCV系列】:https://blog.csdn.net/shuiyixin/article/category/7581855
如果你想了解更多有关于计算机视觉、OpenCV、机器学习、深度学习等相关技术的内容,想与更多大佬一起沟通,那就扫描下方二维码加入我们吧!
上节课我们讲了算子,这节课我们来回顾一下算子的概念:
狭义的算子实际上是指从一个函数空间到另一个函数空间(或它自身)的映射。
广义的算子的定义只要把上面的空间推广到一般空间,可以是向量空间,赋范向量空间,内积空间,或更进一步,Banach空间,Hilbert空间都可以。算子还可分为有界的与无界的,线性的与非线性的等等类别。
Sobel 算子 ,其基础来自于一个事实,即在边缘部分,像素值出现”跳跃“或者较大的变化。如果在此边缘部分求取一阶导数,你会看到极值的出现。正如下图所示:
对应的算子的梯度如下:
接下来,我们来说一个新的算子Laplance算子。
还是上面这个图像,我们求一阶导数之后,还能求其二阶导数。这个时候,当初图像上变化最大的位置,二阶导数为0。
首先我们看一下离散的一阶导数的计算方法:
二阶导数就是一阶导数的导数:
因为图像有行列两个方向,所以要两个方向分别求导数:
拉普拉斯算子由OpenCV函数cv :: Laplacian实现。 实际上,由于拉普拉斯算子使用图像的梯度,因此它在内部调用Sobel算子来执行其计算。
接下来我们讲一下API
void Laplacian(
InputArray src,
OutputArray dst,
int ddepth,
int ksize = 3,
double scale = 1,
double delta = 0,
int borderType = BORDER_DEFAULT
);
函数参数含义如下:
(1)InputArray类型的src ,输入图像。
(2)OutputArray类型的dst ,输出图像,图像的大小、通道数和输入图像相同。
(3)int类型的ddepth,目标图像的所需深度。
(4)int类型的ksize,用于计算二阶导数滤波器的孔径大小。大小必须是正数和奇数。
(5)double类型的scale,计算拉普拉斯值的可选比例因子。默认情况下,不应用缩放。
(6)double类型的delta,在将筛选的像素存储到dst中之前添加到这些像素的可选值。说的有点专业了其实就是给所选的像素值添加一个值delta。
(7)int类型的borderType,用于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT。
我们这个函数只需要设置前两个参数,这个函数可以计算图像src的像素绝对值,输出到图像dst。
#include
#include
using namespace std;
using namespace cv;
int main()
{
Mat img, gx, gy, src;
img = imread("E:/image/girl2.png");
if (!img.data)
{
cout << "could not load image !";
return -1;
}
imshow("【输入图像】", img);
Sobel(img, gx, CV_16S, 1, 0);
Sobel(img, gy, CV_16S, 0, 1);
convertScaleAbs(gx, gx);
convertScaleAbs(gy, gy);
addWeighted(gx, 0.5, gy, 0.5, 0, src);
imshow("【输出图像】", src);
waitKey(0);
return 0;
}
4、执行结果
我们也把上节课的两个算子执行结果拿过来,进行对比:
大家也可以自己尝试一下呀,一定要多做练习!