赞
踩
前面我们介绍过图像的梯度,其定义是根据微积分的定义在二维离散函数中推导出来的。梯度只是一个工具,方法,核心目的是得到像素点与其相邻像素的灰度值变化情况,并通过这种变化来增强图像。这种原始定义的梯度只是这种灰度值变化情况的度量工具。
假设某像素与其8领域用如下矩阵表示:
那么,根据图像梯度的定义:
gx = z8 - z5
gy = z6 - z5
上面提到,这种原始定义的梯度只是这种灰度值变化情况的度量工具,这种度量工具只有这一种吗?显然不是的!
z9-z5算不算灰度值的变化?z1-z5呢?z7-z5呢?z4-z5呢?z3-z5呢?
我们利用梯度的本质目的,是要找到某像素与其相邻像素的灰度差值,并放大这种差值,从而用于图像增强。而原始定义的梯度计算方法只是灰度差值计算方法中的一种,还可以有其它计算方法来度量这种变化。
为简化起见,我们把这些计算方法统称为梯度算子。根据不同的相邻像素差值计算得到的效果可能有所不同,但基本原理是一致的。
Robert使用一个2x2的模板,而且是对角线做差,其差分为:
用下面的矩阵表示有:
简化为绝对值方法:
Roberts边缘检测算子是一种利用局部差分算子寻找边缘的算子,Robert算子图像处理后结果边缘不是很平滑。经分析,由于Robert算子通常会在图像边缘附近的区域内 产生较宽的响应,故采用上述算子检测的边缘图像常需做细化处理,边缘定位的精度不是很高。
witt算子是一种一阶微分算子的边缘检测,利用像素点上下、左右邻点的灰度差,在边缘处达到极值检测边缘,去掉部分伪边缘,对噪声具有平滑作用 。其原理是在图像空间利用两个方向模板与图像进行邻域卷积来完成的,这两个方向模板一个检测水平边缘,一个检测垂直边缘。
相比Roberts算子,Prewitt算子对噪声有抑制作用,抑制噪声的原理是通过像素平均,因此噪声较多的图像处理得比较好,但是像素平均相当于对图像的低通滤波,所以Prewitt算子对边缘的定位却不如Roberts算子。
在3*3模板中,分别表示水平和垂直的梯度:
Mat src=imread("D:/test/src.jpg",0); Mat dst_x, dst_y,dst; imshow("src", src); Mat kernelx = (Mat_<double>(3, 3) << 1, 1, 1, 0, 0, 0, -1, -1, -1); Mat kernely = (Mat_<double>(3, 3) << -1, 0, 1, -1, 0, 1, -1, 0, 1); filter2D(src, dst_x, CV_16S, kernelx); filter2D(src, dst_y, CV_16S, kernely); convertScaleAbs(dst_x, dst_x); convertScaleAbs(dst_y, dst_y); addWeighted(dst_x, 0.5, dst_y, 0.5, 0, dst); imshow("dst_x", dst_x); imshow("dst_y", dst_y); imshow("dst", dst);
sobel在Prewitt算子的基础上改进的,在中心系数上使用一个权值2,相比较Prewitt算子,Sobel模板能够较好的抑制(平滑)噪声。
Sobel算子:
上述所有算子都是通过求一阶导数来计算梯度的,用于线的检测,在图像处理中,通常用于边缘检测。在图像处理过程中,除了检测线,有时候也需要检测特殊点,这就需要用二阶导数进行检测。
无论是Sobel还是Prewitt都是求单方向上颜色变化的一阶导(Sobel相比Prewitt增加了权重),那么如何才能反映空间上的颜色变化的一个极值呢?
在一阶导数的极值位置,二阶导数为0。所以我们也可以用这个特点来作为检测图像边缘的方法。 但是, 二阶导数的0值不仅仅出现在边缘(它们也可能出现在无意义的位置),但是我们可以过滤掉这些点。
在实际情况中我们不可能用0作为判断条件,而是设定一个阈值,这就引出来Laplace算子。
模板中心位置的数字是-8而不是-4,是因为要使这些系数之和为0。
用lapacian算子图像进行卷积运算时,当响应的绝对值超过指定阈值时,那么该点就是被检测出来的孤立点。
函数说明
计算图像的拉普拉斯算子。
该函数通过将使用Sobel运算符计算的第二个x和y导数相加来计算源图像的拉普拉斯算子:
当ksize>1时:
当ksize==1时,拉普拉斯算子是通过以下3×3的滤波图像来计算:
laplacian算子只需要调用一次,不必分别指定X,Y方向导数。
函数声明
void cv::Laplacian (
InputArray src,
OutputArray dst,
int ddepth,
int ksize = 1,
double scale = 1,
double delta = 0,
int borderType = BORDER_DEFAULT
)
Python:
dst = cv.Laplacian( src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]] )
函数参数
src | 源图像。 |
---|---|
dst | 与src具有相同大小和相同通道数的目标图像。 |
ddepth | 目标图像的所需深度。 |
ksize | 用于计算二阶导数滤波器的过滤器大小 |
scale | 计算的拉普拉斯算子值的可选比例因子。默认情况下,不应用缩放。有关详细信息,请参阅getDerivKernels。 |
delta | 在将结果存储在dst之前添加到结果中的可选增量值。 |
应用举例
Mat src=imread("D:/test/src.jpg",0);
Mat dst_x, dst_y,dst;
imshow("src", src);
Laplacian(src, dst, CV_64F);
convertScaleAbs(dst, dst);
imshow("dst", dst);
当ksize>1时:
学习:
图像边缘提取——梯度算子、Roberts算子、prewitt算子、Sobel算子、Kirsch算子、LOG算子的matlab实现
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。