1.边缘提取
前置知识
图像中的低频信号和高频信号也叫做低频分量和高频分量。简单一点说,图像中的高频分量,指的是图像强度(亮度/灰度)变化剧烈的地方,也就是边缘(轮廓); 图像中的低频分量,指的是图像强度(亮度/灰度)变换平缓的地方,也就是大片色块的地方。 人眼对图像中的高频信号更为敏感。
定义了解
图象的边缘是指图象局部区域亮度变化显著的部分,该区域的灰度剖面一般可以看作是一个阶跃,既从一个灰度值在很小的缓冲区域内急剧变化到另一个灰度相差较大的灰度值。(边缘提取,指数字图像处理中,对于图片轮廓的一个处理。对于边界处,灰度值变化比较剧烈的地方,就定义为边缘。) 边缘有正负之分,就像导数有正值也有负值一样:由暗到亮为正,由亮到暗为负。 求边缘幅度的算法:sobel、Roberts、prewitt、Laplacian、Canny算子。(Canny算子效果比其他的都要好) 边缘提取的应用:语义分割,实例分割
2.原理
具体原理
关于边缘检测的基础来自于一个事实,即在边缘部分,像素值出现”跳跃“或者较大的变化。如果在此边缘部分求取一阶导数,就会看到极值的出现。 而在一阶导数为极值的地方,二阶导数为0,基于这个原理,就可以进行边缘检测。
步骤
1)滤波:边缘检测的算法主要是基于图像强度的一阶和二阶导数,但导数通常对噪声很敏感,因此必须采用滤波器来改善与噪声有关的边缘检测器的性能。常见的滤波方法主要有高斯滤波。 2)增强:增强边缘的基础是确定图像各点邻域强度的变化值。增强算法可以将图像灰度点邻域强度值有显著变化的点凸显出来。在具体编程实现时,可通过计算梯度幅值来确定。 3)检测:经过增强的图像,往往邻域中有很多点的梯度值比较大,而在特定的应用中,这些点并不是我们要找的边缘点,所以应该采用某种方法来对这些点进行取舍。实际工程中,常用的方法是通过阈值化方法来检测。
3.Prewitt、Sobel算子
4.Canny算法
介绍
Canny是目前最优秀的边缘检测算法,其目标为找到一个最优的边缘,其最优边缘的定义为: 1、好的检测:算法能够尽可能的标出图像中的实际边缘 2、好的定位:标识出的边缘要与实际图像中的边缘尽可能接近 3、最小响应:图像中的边缘只能标记一次
算法
灰度化
首先,先进行灰度化,因为RGB3通道对于边缘提取而言,我们并不care,灰度化后能提高效率。
高斯滤波
接着,我们利用高斯滤波对图像进行降噪。
检测图像的边缘
可以利用如Prewitt,Sobel算子等检测图像中的水平、垂直和对角边缘。
*非极大值抑制(NMS)
解释:当我们完成上一步,我们就获得许多边缘,我们要尽可能找到局部最优的边缘,减少冗余。 如上图,我们要判断C点是否为真正的边缘(此时我们已经知道了C点的像素值)。假设,如果C点的像素值不是最大的,那么最大值就是在C的梯度方向上(分别交于DTemp1,DTemp2),我们要将三点进行比较。但是得注意:这里Dtemp1和Dtemp2是虚拟的点,所以要通过线性插值求出他们的值,再进行判断。
双阈值检测
代码实现
从下面的2张图,我们可以看出。当minval和maxval越小时,所保留的边缘信息更多。
import cv2
import numpy as np
'''
cv2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient ]]])
必要参数:
第一个参数是需要处理的原图像,该图像必须为单通道的灰度图;
第二个参数是滞后阈值1;
第三个参数是滞后阈值2。
'''
img = cv2.imread("lenna.png", 1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow("canny", cv2.Canny(gray, 100, 200))
cv2.waitKey()
cv2.destroyAllWindows()
cv2.imshow("canny", cv2.Canny(gray, 50, 100))
|