当前位置:数据分析 > Opencv+Python笔记(七)边缘检测原理

Opencv+Python笔记(七)边缘检测原理

  • 发布:2023-10-01 10:46

:梯度计算总是从右减左

1。边缘检测原理

边缘检测是图像处理和计算机视觉中的一个基本问题。边缘检测的目的是识别数字图像中亮度变化明显的点。它用于确定图片中对象的边界(边缘)或区域。边缘检测可以大大减少小数据量并消除不相关的问题

在边缘检测之前,我们一般需要进行滤波来平滑图像。这是为了消除图片中的噪点。在边缘检测中,需要对像素亮度进行数值微分,从而导致边缘出现噪声。也就是说,图像中相邻像素(尤其是边缘附近)亮度波动较大的噪声会被我们视为边界,但它并不是我们要寻找的主要边缘结构。

边缘检测的方法有很多种,大多数可以分为两类:基于搜索和基于过零的

对图1的图片进行边缘检测。图2是基于搜索的。图3基于衣领交叉

(1)基于搜索:通过寻找图像一阶导数中的最大值来检测边界,然后利用计算结果来估计边缘的局部方向,通常利用梯度的方向,并且使用这个方向来找到局部梯度模块的最大值。
(2) 基于零交叉:通过寻找图像二阶导数的零交叉来寻找边界。

2。 Sobel 算子(基于搜索)

本质就是梯度运算

Sobel算子需要同时计算图像x和y方向的卷积结果

组合 x 方向和 y 方向即可找到:
{img_3 :aHR0chHM6Ly9pbWctYmxvZy5jc2RuaW1nLmNuLzZkMmM2NmU0ZjYxNTRhNDQ5YmQzNjBkYjIxZDQ0Z TZlLnBuZyNwaWNfY2VudGVy/}
可简化为:

具体卷积步骤:
对于5*6的图像,使用Sobel算子卷积核进行卷积:
深度学习中,原始图像中未计算边界像素的计算:将0像素的原始图像扩展为7 * 8图像:
{ img_6 :aHR0cHM6Ly9pbWctYmxvZy5jc2RuaW1nLmNuLzQwZjY2YWQxMTQyYzRiNzJhOTUwNjY0ZDI3NWYyOTdmLmpwZWcjcGljX2NlbnRlcg==/}
具体示例:对于像素x的(2, 1)梯度计算轴:255 * -1 + 155 * 0 + 215 * 1 + 65 * -2 + 255 * 0 + 255 * 2 + 255 * -1 + 155 * 0 + 215 * 1 结果是 G x G_{x} Gx

Sobel特点:效率要求高但不太在意精细纹理

Opencv API:

gray_x_or_y =cv.索贝尔(src,  d深度, dx, dy dst ksize 比例 增量 , borderType)

输入:
1.src:传入图像;
2.d深度:图像的深度;
3.dx和dy:分别表示x和y方向的偏导数。
4.dst:函数的输出结果存储在dst中
5.ksize:指Sobel算子的大小,即卷积核的大小。必须是奇数 1, 3, 5, 7,默认为 3 。注意:如果ksize = -1,则演变成3*3 Scharr算子。
6.scale:缩放导数的比例常数,默认无缩放系数。
7.borderType:图像边框模式,默认cv2.BORDER_DEFAULT。
输出:
Sobel_x、Sobel_y:图像在x轴或y轴上的梯度计算结果

注:
(1)由于梯度计算总是从右边减去左边,所以结果中可能存在负数和大于255的数字,而原始图像是uint8数据类型(8位)无符号数),Sobel 创建的图像位数不够,需要进行数据类型转换。处理完数据后,使用cv2.convertScaleAbs()函数将其转换回原来的uint8格式,否则图像无法显示(cv2.convertScaleAbs()用于对图像数组进行线性变换,将结果转换为无符号8位整数类型,通常用于调整图像对比度和亮度。)
(2) Sobel算子计算一个方向的梯度,最后使用cv2。 addWeighted() 函数合并 x 和 y 方向的结果

gray_absX = cv2.convertScaleAbs(gray_x)  #格式转换grey_absY = cv2.convertScaleAbs(gray_y)
result_sobel = cv2.addWeighted(gray_absX, alpha ,gray_absX,beta, C)#图像融合

代码:

gray_x = cv2.索贝尔(灰色, cv2.CV_64F, 1, 0, k 尺寸 = 3)
grey_y = cv2.索贝尔(灰色, cv2 .CV_64F,0, 1, k 尺寸 = 3)
grey_absX = cv2.convertScaleAbs(gray_x)
grey_absY = cv2.convertScaleAbs(gray_y)
result_sobel = cv2.addWeighted(gray_absX, 0.5,gray_absX,0.5,0)

三、拉普拉斯算子(基于零穿越)

使用拉普拉斯算子边缘处理可以锐化图像,突出图像亮度变化较快的区域,改善图像的视觉效果。但它对噪声敏感,适用于无噪声图像。使用该算子进行边缘处理之前,先使用高斯滤波器平滑噪声

拉普拉斯卷积核:

Opencv API:

cv2.拉普拉斯算子(src,d深度, dst, ksize, 刻度 增量 边界类型)

输入:
src:输入图像
d深度:图像深度。 -1表示使用与原始图像相同的深度,并且目标图像的深度必须大于或等于原始图像的深度。
ksize:算子的大小,即卷积核的大小,必须为1,3,5,7,默认为3。
scale:缩放导数的缩放常数。默认情况下没有缩放系数。
borderType:图像边框模式,默认cv2.BORDER_DEFAULT。

代码:

gray_la = cv2.拉普拉斯算子(灰色,  cv2.CV_64F)
result_laplacian = cv2.convertScaleAbs(gray_la)

4。糖果边缘检测算法

Canny 边缘检测是最流行的,也是目前公认最好的边缘检测算法。
该算法分为四个部分:
1。消除噪音;
2。计算图像的亮度梯度值;
3。减法假边;
4。双阈值过滤边界;

1。消除噪音

使用高斯滤波器去除大部分噪声,或最大程度地减少不必要的图像细节产生的不必要的边缘。图像平滑

2。计算图像的亮度梯度值

使用Sobel算子计算高斯滤波平滑图像上水平和垂直方向的一阶导数,从而求出边界的梯度和方向
梯度方向分为四类:垂直、水平和两个对角方向

3。减去假边缘(非极大值抑制NMS)

通过将每个像素与周围像素在水平和垂直方向上的梯度值进行比较来去除假边缘。如果某个像素对应的梯度局部最大,即大于其上、下、左、右像素的梯度,则该像素被保留。否则,将像素设置为 0。

4。双阈值过滤边界


通过双阈值筛选真实边界。高于 maxVal 的边界称为边界。梯度值位于(minVal,maxVal)的边界称为边界。如果对边界进行进一步过滤,如果与边界相连,则处理为Boundary,否则丢弃

Opencv API:

dst = cv2.Canny(图像,阈值1, 阈值2)

输入:
图像:输入灰度图像
阈值1:minVal,较小的阈值连接不连续的边缘。
阈值2:maxVal,较大的阈值以检测图像中明显的边缘。
输出:
边缘处理后的结果图像

代码:

result_candy = cv2.Canny(灰色, 0,160)

相关文章