图像边缘检测
目录
- 图像边缘检测
-
- [1 Sobel算子](#1 Sobel算子)
-
- 1.1概念
- [1.2 两个卷积矩阵](#1.2 两个卷积矩阵)
- [1.3 函数及参数理解](#1.3 函数及参数理解)
- [1.4 灰度图实际测试](#1.4 灰度图实际测试)
- [1.5 BGR图测试](#1.5 BGR图测试)
- [2 Scharr算子](#2 Scharr算子)
-
- 2.1概念
- [2.2 实际测试](#2.2 实际测试)
- [3 Laplacian算子](#3 Laplacian算子)
-
- 3.1概念
- [3.2 函数](#3.2 函数)
- [3.3 实际测试](#3.3 实际测试)
- [4 Canny边缘检测](#4 Canny边缘检测)
-
- [4.1 概念](#4.1 概念)
- [4.2 步骤](#4.2 步骤)
- [4.3 优点](#4.3 优点)
- [4.4 函数及参数理解](#4.4 函数及参数理解)
- [4.5 实际测试](#4.5 实际测试)
1 Sobel算子
1.1概念
是一种用于图像处理的算法,主要用于边缘检测。它通过计算图像亮度的空间梯度来突出显示图像中的边缘。Sobel算子包含两个核(卷积矩阵),分别用于检测水平边缘和垂直边缘。
1.2 两个卷积矩阵
1.3 函数及参数理解
- cv2.Sobel(图片变量,数据类型,dx=1/0,dy=0/1) ,水平/垂直获取轮廓
- 数据类型为数字-1时,与图片类型相同,为cv2.CV_64F时,为浮点型有正负
- dx为1时水平获取,dy为1时垂直获取,不能同时为1
- cv2.convertScaleAbs(轮廓变量),对轮廓变量内的数值绝对值化,使其可以显示出来
- cv2.addWeighted(x轮廓变量,1,y轮廓变量,1,0),组合轮廓变量使其完整
1.4 灰度图实际测试
代码展示:
python
import cv2
yuan = cv2.imread('yuan.png')
cv2.imshow('yuan',yuan)
cv2.waitKey(0)
yuan_1 = cv2.Sobel(yuan,-1,dx=1,dy=0)
yuan_64F = cv2.Sobel(yuan,cv2.CV_64F,dx=1,dy=0)
yuan_Abs = cv2.convertScaleAbs(yuan_64F)
yuan_1_y = cv2.Sobel(yuan,-1,dx=0,dy=1)
yuan_64F_y = cv2.Sobel(yuan,cv2.CV_64F,dx=0,dy=1)
yuan_Abs_y = cv2.convertScaleAbs(yuan_64F_y)
# 组合
yuan_xy = cv2.addWeighted(yuan_Abs,1,yuan_Abs_y,1,0)
cv2.imshow('yuan_1',yuan_1)
cv2.waitKey(0)
cv2.imshow('yuan_64F',yuan_64F)
cv2.waitKey(0)
cv2.imshow('yuan_Abs',yuan_Abs)
cv2.waitKey(0)
cv2.imshow('yuan_1_y',yuan_1_y)
cv2.waitKey(0)
cv2.imshow('yuan_64F_y',yuan_64F_y)
cv2.waitKey(0)
cv2.imshow('yuan_Abs_y',yuan_Abs_y)
cv2.waitKey(0)
cv2.imshow('yuan_xy',yuan_xy )
cv2.waitKey(0)
运行结果:
1.5 BGR图测试
代码展示:
python
import cv2
at1 = cv2.imread('at1.png')
cv2.imshow('at1',at1)
cv2.waitKey(0)
at1_64F = cv2.Sobel(at1,cv2.CV_64F,dx=1,dy=0)
at1_Abs = cv2.convertScaleAbs(at1_64F)
at1_64F_y = cv2.Sobel(at1,cv2.CV_64F,dx=0,dy=1)
at1_Abs_y = cv2.convertScaleAbs(at1_64F_y)
# 组合
at1_xy = cv2.addWeighted(at1_Abs,1,at1_Abs_y,1,0)
cv2.imshow('at1_64F',at1_64F)
cv2.waitKey(0)
cv2.imshow('at1_Abs',at1_Abs)
cv2.waitKey(0)
cv2.imshow('at1_64F_y',at1_64F_y)
cv2.waitKey(0)
cv2.imshow('at1_Abs_y',at1_Abs_y)
cv2.waitKey(0)
cv2.imshow('at1y_xy_sobel',at1_xy )
cv2.waitKey(0)
运行结果:
2 Scharr算子
2.1概念
它是Sobel算子的一种改进版本,专门用于计算图像的梯度。Scharr算子与Sobel算子的主要区别在于它们的卷积核不同。Scharr算子在处理边缘时比Sobel算子具有更高的精度,但它们在计算时间和复杂度上是一样的,函数cv2.Scharr(),内在参数与Sobel算子相同,同样需要绝对值和组合。
2.2 实际测试
代码展示:
python
import cv2
at1 = cv2.imread('at1.png')
cv2.imshow('at1',at1)
cv2.waitKey(0)
at1_64F = cv2.Sobel(at1,cv2.CV_64F,dx=1,dy=0)
at1_Abs = cv2.convertScaleAbs(at1_64F)
at1_64F_y = cv2.Sobel(at1,cv2.CV_64F,dx=0,dy=1)
at1_Abs_y = cv2.convertScaleAbs(at1_64F_y)
# # 组合
at1_xy = cv2.addWeighted(at1_Abs,1,at1_Abs_y,1,0)
cv2.imshow('at1y_xy_sobel',at1_xy )
cv2.waitKey(0)
# # scharr
at1_64F_Scharr = cv2.Scharr(at1,cv2.CV_64F,dx=1,dy=0)
at1_Abs_Scharr = cv2.convertScaleAbs(at1_64F_Scharr)
at1_64F_y_Scharr = cv2.Scharr(at1,cv2.CV_64F,dx=0,dy=1)
at1_Abs_y_Scharr = cv2.convertScaleAbs(at1_64F_y_Scharr)
at1_xy_Scharr = cv2.addWeighted(at1_Abs_Scharr,1,at1_Abs_y_Scharr,1,0)
cv2.imshow('at1y_xy_Scharr',at1_xy_Scharr)
cv2.waitKey(0)
运行结果:
3 Laplacian算子
3.1概念
是一种用于边缘检测的数学工具。在图像处理中,Laplacian算子通常用于找到图像中的亮度快速变化的区域,这些区域往往对应于图像中的边缘或者物体边界。
不需要再进行图片组合。
3.2 函数
- cv2.Laplacian(图片变量,数据类型)
- cv2.convertScaleAbs(轮廓变量)
3.3 实际测试
代码展示:
python
import cv2
yuan = cv2.imread('yuan.png')
cv2.imshow('yuan',yuan)
cv2.waitKey(0)
at1 = cv2.imread('at1.png')
cv2.imshow('at1',at1)
cv2.waitKey(0)
## Sobel
at1_64F = cv2.Sobel(at1,cv2.CV_64F,dx=1,dy=0)
at1_Abs = cv2.convertScaleAbs(at1_64F)
at1_64F_y = cv2.Sobel(at1,cv2.CV_64F,dx=0,dy=1)
at1_Abs_y = cv2.convertScaleAbs(at1_64F_y)
# # # 组合
at1_xy = cv2.addWeighted(at1_Abs,1,at1_Abs_y,1,0)
cv2.imshow('at1y_xy_sobel',at1_xy )
cv2.waitKey(0)
# # # scharr
at1_64F_Scharr = cv2.Scharr(at1,cv2.CV_64F,dx=1,dy=0)
at1_Abs_Scharr = cv2.convertScaleAbs(at1_64F_Scharr)
at1_64F_y_Scharr = cv2.Scharr(at1,cv2.CV_64F,dx=0,dy=1)
at1_Abs_y_Scharr = cv2.convertScaleAbs(at1_64F_y_Scharr)
at1_xy_Scharr = cv2.addWeighted(at1_Abs_Scharr,1,at1_Abs_y_Scharr,1,0)
cv2.imshow('at1y_xy_Scharr',at1_xy_Scharr)
cv2.waitKey(0)
# laplacian
at1_64F_Laplacian = cv2.Laplacian(at1,cv2.CV_64F)
at1_Abs_Laplacian = cv2.convertScaleAbs(at1_64F_Laplacian)
cv2.imshow('at1_Abs_Laplacian ',at1_Abs_Laplacian )
cv2.waitKey(0)
yuan_64F_Laplacian = cv2.Laplacian(yuan,cv2.CV_64F)
yuan_Abs_Laplacian = cv2.convertScaleAbs(yuan_64F_Laplacian)
cv2.imshow('yuan_Abs_Laplacian ',yuan_Abs_Laplacian )
cv2.waitKey(0)
运行结果:
4 Canny边缘检测
4.1 概念
Canny边缘检测是一种流行的图像处理算法,用于检测图像中的边缘,并被认为是边缘检测中最优的算法之一。
4.2 步骤
- 噪声降低 :
- 使用高斯滤波器对图像进行平滑处理,以减少图像中的噪声。高斯滤波器可以有效地降低噪声,同时保持边缘的尖锐度。
- 计算梯度幅度和方向 :
- 通过计算图像中每个像素点的梯度幅度和方向,来确定可能的边缘。通常使用Sobel算子来计算水平和垂直方向的梯度。
- 非极大值抑制 :
- 对梯度幅度进行非极大值抑制,这一步会沿着梯度方向检查每个像素,只有当该像素的梯度幅度是局部最大值时,才将其保留为边缘候选点,否则将其抑制(即设为0)。
- 双阈值确定边缘 :
- 应用两个阈值(高阈值和低阈值)来确定真实边缘和潜在边缘。梯度幅度高于高阈值的像素被标记为强边缘,梯度幅度低于低阈值的像素被抑制,梯度幅度在两个阈值之间的像素被标记为弱边缘。
- 边缘跟踪和边缘连接 :
- 最后,通过边缘跟踪和边缘连接来强化边缘。通常,算法会检查弱边缘像素是否与强边缘像素相连,如果是,则将其标记为强边缘。这个过程可以确保边缘是连续的。
4.3 优点
Canny边缘检测算法的优点包括:
- 良好的检测效果:Canny算法能够检测到图像中的真实边缘,同时抑制噪声。
- 边缘定位精度:由于使用了梯度方向,Canny算法能够更精确地定位边缘。
- 参数可调:通过调整高斯滤波器的大小、阈值等参数,可以适应不同的图像和边缘检测需求。
Canny边缘检测算法在计算机视觉和图像处理领域得到了广泛应用,尤其是在需要精确边缘检测的场合。
4.4 函数及参数理解
- cv2.Canny(图像变量,低阈值,高阈值),低于低阈值为0,高于高阈值为255
4.5 实际测试
代码展示:
python
import cv2
at1 = cv2.imread('at1.png')
cv2.imshow('at1',at1)
cv2.waitKey(0)
at1_64F = cv2.Sobel(at1,cv2.CV_64F,dx=1,dy=0)
at1_Abs = cv2.convertScaleAbs(at1_64F)
at1_64F_y = cv2.Sobel(at1,cv2.CV_64F,dx=0,dy=1)
at1_Abs_y = cv2.convertScaleAbs(at1_64F_y)
#
# # # 组合
at1_xy = cv2.addWeighted(at1_Abs,1,at1_Abs_y,1,0)
cv2.imshow('at1y_xy_sobel',at1_xy )
cv2.waitKey(0)
# #
# # scharr
at1_64F_Scharr = cv2.Scharr(at1,cv2.CV_64F,dx=1,dy=0)
at1_Abs_Scharr = cv2.convertScaleAbs(at1_64F_Scharr)
at1_64F_y_Scharr = cv2.Scharr(at1,cv2.CV_64F,dx=0,dy=1)
at1_Abs_y_Scharr = cv2.convertScaleAbs(at1_64F_y_Scharr)
at1_xy_Scharr = cv2.addWeighted(at1_Abs_Scharr,1,at1_Abs_y_Scharr,1,0)
cv2.imshow('at1y_xy_Scharr',at1_xy_Scharr)
cv2.waitKey(0)
# laplacian
at1_64F_Laplacian = cv2.Laplacian(at1,cv2.CV_64F)
at1_Abs_Laplacian = cv2.convertScaleAbs(at1_64F_Laplacian)
cv2.imshow('at1_Abs_Laplacian ',at1_Abs_Laplacian )
cv2.waitKey(0)
# # canny
at1_canny = cv2.Canny(at1,130,255)
cv2.imshow('at1_canny',at1_canny )
cv2.waitKey(0)
运行结果: