广州网站开发企业,想做一个网站,东莞短视频推广哪个平台好,wordpress文章类插件1 边缘检测介绍
图像边缘检测技术是图像处理和计算机视觉等领域最基本的问题#xff0c;也是经典的技术难题之一。如何快速、精确地提取图像边缘信息#xff0c;一直是国内外的研究热点#xff0c;同时边缘的检测也是图像处理中的一个难题。早期的经典算法包括边缘算子方法… 1 边缘检测介绍
图像边缘检测技术是图像处理和计算机视觉等领域最基本的问题也是经典的技术难题之一。如何快速、精确地提取图像边缘信息一直是国内外的研究热点同时边缘的检测也是图像处理中的一个难题。早期的经典算法包括边缘算子方法、曲面拟合的方法、模板匹配方法、阈值法等。
近年来随着数学理论与人工智能技术的发展出现了许多新的边缘检测方法如Roberts、Laplacan、Canny等图像的边缘检测方法。这些方法的应用对于高水平的特征提取、特征描述、目标识别和图像理解有重大的影响。然而在成像处理的过程中投影、混合、失真和噪声等会导致图像模糊和变形这使得人们一直致力于构造具有良好特性的边缘检测算子。
1.1 什么是边缘检测
边缘检测是图像处理和计算机视觉中的基本问题边缘检测的目的是标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了属性的重要事件和变化包括深度不连续、表面方向不连续、物质属性变化和场景照明变化。边缘检测特征是提取中的一个研究领域。图像边缘检测大幅度地减少了数据量并且剔除了可以认为不相关的信息保留了图像重要的结构属性。 1.2 边缘检测的方法
人类视觉系统认识目标的过程分为两步首先把图像边缘与背景分离出来然后到图像的细节辨认出图像的轮廓。计算机视觉正是模仿人类视觉的过程。
因此在检测物体边缘时先对轮廓点进行粗略检测然后通过链接规则把原来检测到的轮廓点连接起来同时检测和连接遗漏的边界点及去除虚假的边界点。图像的边缘是图像的重要特征是计算机视觉、模式识别等的基础因此边缘检测是图像处理中一个重要的环节。然而边缘检测是图像处理中的一个难题因为实际景物图像的边缘往往是各种类型的边缘及它们模糊化后结果的组合且实际图像信号存在噪声。噪声和边缘都属于高频信号很难用频带做取舍。
边缘是指图像周围像素灰度有阶跃变化或屋顶状变化的像素集合存在于目标与背景、目标与目标、区域与区域、基元与基元之间。边缘具有方向和幅度两个特征沿边缘走向像素值变化比较平缓垂直于边缘走向像素值变化比较剧烈可能呈现阶跃状也可能呈现斜坡状。因此边缘可以分为两种 一种为阶跃性边缘两边的像素灰度值有着明显的不同 另一种为屋顶状边缘位于灰度值从增加到减少的变化转折点。
对于阶跃性边缘二阶方向导数在边缘处呈零交叉对于屋顶状边缘二阶方向导数在边缘处取极值。有许多方法可以用于边缘检测绝大部分可以划分为两类基于搜索的一类和基于零穿越的一类。 基于搜索通过寻找图像一阶导数中的最大值来检测边界然后利用计算结果估计边缘的局部方向通常采用梯度的方向并利用此方向找到局部梯度模的最大值代表算法是Sobel算子和Scharr算子。 基于零穿越通过寻找图像二阶导数零穿越来寻找边界代表算法是Laplacian算子。 1.3 典型算子比较
算子优缺点Roberts对具有陡峭的低噪声的图像处理效果较好但利用Roberts算子提取边缘的结果是边缘比较粗因此边缘定位不是很准确Sobel对灰度渐变和噪声较多的图像处理效果比较好Sobel算子对边缘定位比较准确Kirsch对灰度渐变和噪声较多的图像处理效果较好Prewitt 对灰度渐变和噪声较多的图像处理效果较好Laplacian对图像中的阶跃性边缘点定位准确对噪声非常敏感丢失一部分边缘的方向信息造成一些不连续的检测边缘LoGLoG算子经常出现双边缘像素边界而且该检测算法对噪声比较敏感所以很少用LoG算子检测边缘而是用来判断边缘像素是位于图像的明区还是暗区Canny此方法不容易受噪声的干扰能够检测到真正的弱边缘。在edge函数中最有效的边缘检测方法是Canny方法。该方法的优点在于使用两种不同的阈值分别检测强边缘和弱边缘并且仅当弱边缘和强边缘相连时才将弱边缘包含在输出图像中。因此这种方法不容易被噪声”填充“更容易检测出真正的弱边缘。
2 opencv中叠加Sobel算子与Laplacian算子实现边缘检测
openCV 还可以将不同算法结合起来达到更好的效果本例使用Sobel算子 结合 Laplacian算子 实现图像边缘检测。
2.1 Sobel算子检测原理
对于不连续的函数一阶导数可以写作 或 所以有 假设要处理的图像为I在两个方向求导: 水平变化: 将图像I 与奇数大小的模版进行卷积结果为Gx 。比如当模板大小为3时, Gx为 垂直变化: 将图像I 与奇数大小的模版进行卷积结果为Gy 。比如当模板大小为3时,Gy为 在图像的每一点结合以上两个结果求出 统计极大值所在的位置就是图像的边缘。
注意当内核大小为3时, 以上Sobel内核可能产生比较明显的误差 为解决这一问题我们使用Scharr函数但该函数仅作用于大小为3的内核。该函数的运算与Sobel函数一样快但结果却更加精确其计算方法为: scharr算子和sobel的原理一致就是Gx和Gy参数的大小不同也就是卷积核中各元素的权不同其他都一样scharr算子对于边界的梯度计算效果更精确。
Laplacian算子是一种图像处理中常用的边缘检测算子它用于检测图像中的边缘和轮廓。该算子计算图像中每个像素点的二阶导数从而突出图像中灰度值变化较大的区域这些区域通常对应图像的边缘或者轮廓。
2.2 Laplacian算子检测原理
Laplacian是利用二阶导数来检测边缘 。 因为图像是 “2维”, 我们需要在两个方向求导如下式所示 那不连续函数的二阶导数是 那使用的卷积核是 Laplacian算子的一种常用形式是二维离散Laplacian算子表示为 0 1 01 -4 10 1 0
该算子是一个3x3的矩阵它对应的是图像中每个像素点的上、下、左、右四个方向的像素值以及像素点本身的像素值之间的差值。
应用Laplacian算子的过程如下 将3x3的Laplacian算子依次对图像中的每个像素点进行卷积操作。 将卷积结果作为图像的每个像素点的新像素值。 对于卷积结果如果像素值较大则表示该像素点周围灰度值变化较大可能是图像中的边缘或轮廓。
Laplacian 算子类似二阶 Sobel 导数需要计算两个方向的梯度值。
Laplacian 算子类似二阶 Sobel 导数需要计算两个方向的梯度值。例如在图 9-25 中 左图是 Laplacian 算子。 右图是一个简单图像其中有 9 个像素点。 计算像素点 P5 的近似导数值如下
P5lap (P2 P4 P6 P8) - 4·P5
图 9-26 展示了像素点与周围点的一些实例其中 在左图中像素点 P5 与周围像素点的值相差较小得到的计算结果值较小边缘不明显。 在中间的图中像素点 P5 与周围像素点的值相差较大得到的计算结果值较大边缘较明显。 在右图中像素点 P5 与周围像素点的值相差较大得到的计算结果值较大边缘较明显。 需要注意在上述图像中计算结果的值可能为正数也可能为负数。所以需要对计算结果取绝对值以保证后续运算和显示都是正确的。 2.3 sobel函数原型
Sobel_x_or_y cv2.Sobel(src, ddepth, dx, dy, dst, ksize, scale, delta, borderType)
参数 src传入的图像 ddepth: 图像的深度 dx和dy: 指求导的阶数0表示这个方向上没有求导取值为0、1。 ksize: 是Sobel算子的大小即卷积核的大小必须为奇数1、3、5、7默认为3。 注意如果ksize-1就演变成为3x3的Scharr算子。 scale缩放导数的比例常数默认情况为没有伸缩系数。 borderType图像边界的模式默认值为cv2.BORDER_DEFAULT。
Sobel函数求完导数后会有负值还有会大于255的值。而原图像是uint8即8位无符号数所以Sobel建立的图像位数不够会有截断。因此要使用16位有符号的数据类型即cv2.CV_16S。处理完图像后再使用cv2.convertScaleAbs()函数将其转回原来的uint8格式否则图像无法显示。
Sobel算子是在两个方向计算的最后还需要用cv2.addWeighted( )函数将其组合起来
Scale_abs cv2.convertScaleAbs(x) # 格式转换函数
result cv2.addWeighted(src1, alpha, src2, beta) # 图像混合
2.4 Laplacian函数原型
laplacian cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])
参数 Src: 需要处理的图像 Ddepth: 图像的深度-1表示采用的是原图像相同的深度目标图像的深度必须大于等于原图像的深度 ksize算子的大小即卷积核的大小必须为1,3,5,7。
2.5 叠加函数原型
out cv2.add(src1, src2, dstNone, maskNone, dtypeNone)
参数说明 src1、src2需要相加的两副大小和通道数相等的图像或一副图像和一个标量标量即单一的数值 dst可选参数输出结果保存的变量默认值为None。 如果为非None输出图像保存到dst对应实参中其大小和通道数与输入图像相同图像的深度即图像像素的位数由dtype参数或输入图像确认 mask图像掩膜可选参数为8位单通道的灰度图像用于指定要更改的输出图像数组的元素即输出图像像素只有mask对应位置元素不为0的部分才输出否则该位置像素的所有通道分量都设置为0 dtype可选参数输出图像数组的深度即图像单个像素值的位数如RGB用三个字节表示则为24位。
返回值
out相加的结果图像 2.3 算子叠加代码
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt# 1 读取图像
img cv.imread(../data/lena.jpeg)
img cv.cvtColor(img, cv.COLOR_BGR2RGB)# 2 计算Sobel卷积结果
x cv.Sobel(img, cv.CV_16S, 1, 0)
y cv.Sobel(img, cv.CV_16S, 0, 1)# 3 将数据进行转换
Scale_absX cv.convertScaleAbs(x) # convert 转换 scale 缩放
Scale_absY cv.convertScaleAbs(y)# 4 结果合成
result cv.addWeighted(Scale_absX, 0.5, Scale_absY, 0.5, 0)# 5 laplacian转换
result2 cv.Laplacian(img, cv.CV_16S)
Scale_abs cv.convertScaleAbs(result)# 6 叠加图像
final cv.add(result, Scale_abs)# 7 图像显示
plt.figure(figsize(10, 8), dpi100)
plt.subplot(121), plt.imshow(img), plt.title(original)
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(final, cmapplt.cm.gray), plt.title(final)
plt.xticks([]), plt.yticks([])
plt.show()
运行代码显示