【学习OpenCV4】OpenCV边缘检测算法总结

本文分享内容来自图书《学习OpenCV 4:基于Python的算法实战》,该书内容如下:

1章 OpenCV快速入门;
第2章 图像读写模块imgcodecs;
第3章 核心库模块core;
第4章 图像处理模块imgproc(一);
第5章 图像处理模块imgproc(二);
第6章 可视化模块highgui;
第7章 视频处理模块videoio;
第8章 视频分析模块video;
第9章 照片处理模块photo;
第102D特征模块features2d;
第11章 相机标定与三维重建模块calib3d;
第12章 传统目标检测模块objdetect;
第13章 机器学习模块ml;
第14章 深度神经网络模块dnn

欢迎关注图书《深度学习计算机视觉实战》与《学习OpenCV4:基于Python的算法实战》。

在这里插入图片描述

边缘是图像中非常重要的特征,在图像识别、目标检测等领域发挥着重要的作用。OpenCV封装了常用的边缘检测算法,如Sobel,Scharr,Laplacian和Canny边缘检测算法,本节介绍这些算法的使用方法。

4.7.1 案例44:Sobel边缘检测

OpenCV中提供了Sobel边缘检测的函数Sobel,函数定义如下:

dst = Sobel(src, ddepth, dx, dy, dst=None, ksize=None, scale=None, delta=None, borderType=None)

参数说明如下:
src,输入图像;
ddepth,输出图像的深度,若设置为-1,则深度与输入图像深度相同;
dx,计算x方向导数;
dy,计算y方向导数;
dst,输出图像(返回值);
ksize,核的大小;
scale,梯度计算结果的放大比例;
delta,图像存储前可以将像素值增加delta数值,默认为0;
borderType,边界模式,由BorderTypes定义(见3.4.5节)。
本案例调用Sobel函数进行边缘检测分为了三步,第一步计算x方向的边缘,第二步计算y方向边缘,第三步将x和y方向的边缘叠加形成图像的边缘。
本案例使用的输入图像为图3.10,案例代码如下:

import cv2

src = cv2.imread("src.jpg")
#高斯滤波
src = cv2.GaussianBlur(src, (3, 3), 0)
#转为灰度图
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
#求x方向边缘
sobel_gradx = cv2.Sobel(gray, -1, 1, 0)
#求y方向边缘
sobel_grady = cv2.Sobel(gray, -1, 0, 1)
#边缘合并
sobel_grad = cv2.addWeighted(sobel_gradx, 0.5, sobel_grady, 0.5, 0)

#图像显示
cv2.imshow("sobel_gradx", sobel_gradx)
cv2.imshow("sobel_grady", sobel_grady)
cv2.imshow("sobel_grad", sobel_grad)
cv2.waitKey(0)
cv2.destroyAllWindows()

计算x方向的边缘结果如图4.23所示。
在这里插入图片描述

图4.23
计算y方向的边缘结果如图4.24所示。
在这里插入图片描述

图4.24
合并后的边缘结果如图4.25所示。
在这里插入图片描述

图4.25
Sobel边缘检测时也可以同时计算x和y方向上的边缘,即将dx和dy同时设置为1,案例代码如下:

import cv2

src = cv2.imread("src.jpg")
#高斯滤波
src = cv2.GaussianBlur(src, (3, 3), 0)
#转为灰度图
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
#Sobel边缘检测,同时计算x和y方向的边缘
sobel_grad = cv2.Sobel(gray, -1, 1, 1)
cv2.imshow("sobel_grad", sobel_grad)
cv2.waitKey(0)
cv2.destroyAllWindows()

计算结果如图4.26所示。
在这里插入图片描述

图4.26

4.7.2 案例45:Scharr边缘检测

Sobel算法边缘检测不是很精准,另外一种对Sobel算法改进的算法为Scharr算法,该算法精度比Sobel算法高且检测速度相当。
OpenCV中提供了Scharr边缘检测的函数Scharr,函数定义如下:

dst = Scharr(src, ddepth, dx, dy, dst=None, scale=None, delta=None, borderType=None)

参数说明如下:
src,输入图像;
ddepth,输出图像的深度,若设置为-1,则深度与输入图像深度相同;
dx,计算x方向导数;
dy,计算y方向导数;
dst,输出图像(返回值);
scale,梯度计算结果的放大比例;
delta,图像存储前可以将像素值增加delta数值,默认为0;
borderType,边界模式,由BorderTypes定义(见3.4.5节)。
Scharr算法的核大小为3,所以和Sobel函数相比,不用设置ksize,其他参数均相同。本案例调用Scharr函数进行边缘检测同样分为了三步,第一步计算x方向的边缘,第二步计算y方向边缘,第三步将x和y方向的边缘叠加形成图像的边缘。
案例代码如下:

import cv2

src = cv2.imread("src.jpg")
#高斯滤波
src = cv2.GaussianBlur(src, (3, 3), 0)
#转为灰度图
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)

#求x方向边缘
scharr_gradx = cv2.Scharr(gray, -1, 1, 0)
#求y方向边缘
scharr_grady = cv2.Scharr(gray, -1, 0, 1)
#边缘合并
scharr_grad = cv2.addWeighted(scharr_gradx, 0.5, scharr_grady, 0.5, 0)

#图像显示
cv2.imshow("scharr_gradx", scharr_gradx)
cv2.imshow("scharr_grady", scharr_grady)
cv2.imshow("scharr_grad", scharr_grad)
cv2.waitKey(0)
cv2.destroyAllWindows()

计算x方向边缘结果如图4.27所示。
在这里插入图片描述

图4.27
计算y方向边缘结果如图4.28所示。
在这里插入图片描述

图4.28
边缘合并的结果如图4.29所示。
在这里插入图片描述

图4.29

4.7.3 案例46:Laplacian边缘检测

Sobel边缘检测计算的时一阶梯度,而Laplacian边缘检测计算的则是二阶梯度,OpenCV中提供了Laplacian边缘检测的函数Laplacian,函数定义如下:

dst = Laplacian(src, ddepth, dst=None, ksize=None, scale=None, delta=None, borderType=None)

参数说明如下:
src,输入图像;
ddepth,输出图像的深度,若设置为-1,则深度与输入图像深度相同;
dst,输出图像(返回值);
ksize,用于计算二阶导数滤波器的核大小;
scale,梯度计算结果的放大比例;
delta,图像存储前可以将像素值增加delta数值,默认为0;
borderType,边界模式,由BorderTypes定义(见3.4.5节)。
Laplacian边缘检测的案例代码如下:

import cv2

src = cv2.imread("src.jpg")
#高斯滤波
src = cv2.GaussianBlur(src, (3, 3), 0)
#转为灰度图
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
#Laplacian边缘检测
laplacian_grad = cv2.Laplacian(gray, -1)
#图像显示
cv2.imshow("laplacian_grad", laplacian_grad)
cv2.waitKey(0)
cv2.destroyAllWindows()

边缘检测结果如图4.30所示。
在这里插入图片描述

图4.30

4.7.4 案例47:Canny边缘检测

Canny边缘检测算法是传统图像处理边缘检测中效果较好的算法,该算法先计算x和y方向的一阶导数,然后由它们组合为四个方向导数,而方向导数则是(局部最大值的点)组成边缘的候选项。Canny算法中采用了两个阈值,如果像素的梯度大于较大阈值则接受其为轮廓,如果小于较小值则舍弃,介于阈值之间的如果连接到高于阈值的像素则接受,否则就舍弃,算法建议的阈值介于2:1与3:1之间。OpenCV中提供了Canny边缘检测的函数Canny,函数定义如下:
edges = Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None)
参数说明如下:
image,输入图像;
threshold1,阈值1;
threshold2,阈值2;
edges,输出的边缘图像(返回值);
apertureSize,Sobel核大小;
L2gradient,是否使用L2梯度。

Canny边缘检测的案例代码如下:
import cv2

src = cv2.imread(“src.jpg”)
#高斯滤波
src = cv2.GaussianBlur(src, (3, 3), 0)
#转为灰度图
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
#Canny边缘检测
canny_grad = cv2.Canny(gray, 70, 160)
#图像显示
cv2.imshow(“canny_grad”, canny_grad)
cv2.waitKey(0)
cv2.destroyAllWindows()
边缘检测的结果如图4.31所示。
在这里插入图片描述

图4.31

猜你喜欢

转载自blog.csdn.net/lxiao428/article/details/123023619