机器视觉学习(九)—— 边缘检测

目录

一、边缘检测

[1.1 Canny边缘检测](#1.1 Canny边缘检测)

[1.1.1 cv2.Canny函数](#1.1.1 cv2.Canny函数)

[1.1.2 Canny边缘检测示例](#1.1.2 Canny边缘检测示例)

[1.2 角点检测](#1.2 角点检测)

[1.2.1 cv2.goodFeaturesToTrack()函数](#1.2.1 cv2.goodFeaturesToTrack()函数)

[1.2.2 OpenCV角点检测示例代码](#1.2.2 OpenCV角点检测示例代码)

[1.3 直线检测](#1.3 直线检测)

[1.3.1 cv2.HoughLinesP()函数](#1.3.1 cv2.HoughLinesP()函数)

[1.3.2 OpenCV直线检测示例代码](#1.3.2 OpenCV直线检测示例代码)

[1.4 圆形检测](#1.4 圆形检测)

[1.4.1 cv2.HoughCircles()函数](#1.4.1 cv2.HoughCircles()函数)

[1.4.2 OpenCV圆形检测示例代码](#1.4.2 OpenCV圆形检测示例代码)


一、边缘检测

OpenCV中进行边缘检测的一般步骤如下:

**1.**导入OpenCV库并读取图像:

python 复制代码
import cv2
image = cv2.imread('image.jpg', 0)  # 以灰度模式读取图像

在这个步骤中,你需要将图像加载到内存中。你可以选择以灰度模式或彩色模式读取图像。

2. 对图像进行预处理(可选): 根据具体情况,你可以对图像进行平滑处理(如高斯模糊)或增强处理(如直方图均衡化)。这一步骤可以帮助改善边缘检测的结果。

3. 使用边缘检测算法: 在OpenCV中,有多种边缘检测算法可供选择。以下是一些常用的算法:

  • Canny边缘检测算法:
python 复制代码
edges = cv2.Canny(image, threshold1, threshold2)

threshold1threshold2是两个阈值,用于控制边缘检测的敏感度。

  • Sobel算子:
python 复制代码
gradient_x = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)
gradient_y = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)
edges = cv2.sqrt(gradient_x**2 + gradient_y**2)

使用了Sobel算子计算图像的水平和垂直梯度,并将两个梯度的平方和开方得到边缘强度。

**4.**显示或保存结果:

python 复制代码
cv2.imshow('Edges', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()

1.1 Canny边缘检测

Canny边缘检测是一种经典的图像处理算法,也是OpenCV库中常用的边缘检测方法之一。它通过多个步骤来识别图像中的边缘,包括高斯滤波、梯度计算、非最大抑制和双阈值处理。

以下是对Canny边缘检测算法的详细解释:

  1. 高斯滤波:首先,输入图像会经过一个高斯滤波器,以平滑图像并去除噪声。高斯滤波器是一个线性平滑滤波器,它使用一个二维高斯函数来计算图像中每个像素的新值。

  2. 梯度计算:在经过高斯滤波之后,算法会计算每个像素的梯度幅值和方向。梯度幅值表示像素的变化强度,而梯度方向表示变化的方向。

  3. 非最大抑制:接下来,算法会对梯度幅值进行非最大抑制。这个步骤的目的是找出图像中真正的边缘像素,而抑制非边缘的像素。对于每个像素,算法会检查其梯度方向,并与相邻像素进行比较。只有当像素的梯度幅值是该方向上的最大值时,才会被保留为边缘像素,否则会被抑制。

  4. 双阈值处理:最后,算法会将梯度幅值分成两个阈值:低阈值和高阈值。低阈值用于确定弱边缘像素,而高阈值用于确定强边缘像素。具体而言,如果像素的梯度幅值大于高阈值,则被标记为强边缘像素。如果像素的梯度幅值小于低阈值,则被排除。介于两个阈值之间的像素将被视为弱边缘像素,只有在其周围有强边缘像素时才会被保留。

1.1.1 cv2.Canny函数

cv2.Canny()是OpenCV中用于执行Canny边缘检测的函数。它具有以下语法:

python 复制代码
edges = cv2.Canny(image, threshold1, threshold2[, apertureSize[, L2gradient]])

参数说明:

  • image:输入图像。可以是灰度图像或彩色图像。
  • threshold1:低阈值。边缘强度梯度低于该值的像素被认为不是边缘。
  • threshold2:高阈值。边缘强度梯度高于该值的像素被认为是边缘。
  • apertureSize(可选):Sobel算子的孔径大小。默认值为3。
  • L2gradient(可选):一个布尔值,确定计算梯度的方式。如果为True,则使用L2范数计算梯度(更准确但计算量大);如果为False,则使用L1范数计算梯度(快速但不太准确)。默认值为False。

返回值:

  • edges:边缘检测结果图像。是一个二值图像,其中白色像素表示边缘,黑色像素表示背景。

注意:

  • 通常情况下,推荐将threshold1设置为threshold2的1/3到1/2的值。
  • 较小的阈值会产生更多的边缘,但可能有更多的噪声。
  • 较大的阈值会过滤掉较弱的边缘,但可能会丢失一些边缘。
1.1.2 Canny边缘检测示例

下面是OpenCV进行Canny边缘检测的示例代码:

python 复制代码
import cv2

# 读取图像
image = cv2.imread("image.jpg", cv2.IMREAD_GRAYSCALE)

# 执行Canny边缘检测
edges = cv2.Canny(image, 100, 200)

# 显示结果
cv2.imshow("Original Image", image)
cv2.imshow("Canny Edges", edges)
cv2.waitKey(0)
cv2.destroyAllWindows()

调用cv2.Canny函数进行Canny边缘检测。设置低阈值为100,高阈值为200。

1.2 角点检测

角点检测是计算机视觉中的一种关键技术,用于检测图像中的角点或特征点。角点是图像中两条边交汇形成的点,通常具有较高的局部变化和不变性。

OpenCV提供了几种角点检测算法,其中两种常用的方法是Harris角点检测和Shi-Tomasi角点检测。

  1. Harris角点检测: Harris角点检测算法通过计算图像局部区域的灰度变化,判断是否存在角点。Harris角点检测算法的思想是计算每个像素的响应值,响应值较大的像素被认为是角点。它基于图像的一阶和二阶矩来计算特征值,从而判断每个像素是否为角点。

  2. Shi-Tomasi角点检测: Shi-Tomasi角点检测算法是在Harris角点检测算法的基础上进行了改进。Shi-Tomasi角点检测算法使用了每个像素点的最小特征值,即响应最弱的特征值,作为选择角点的准则。这样可以得到比Harris角点检测更好的角点检测结果。

对于这两种角点检测算法,OpenCV提供了相应的函数,可以方便地进行角点检测。通过调整不同的参数,如窗口大小、响应值阈值等,可以得到不同的角点检测结果。

1.2.1 cv2.goodFeaturesToTrack()函数

cv2.goodFeaturesToTrack()是OpenCV中用于角点检测的函数。下面是该函数的详细解释:

python 复制代码
corners = cv2.goodFeaturesToTrack(image, maxCorners, qualityLevel, minDistance, mask=None, blockSize=None, useHarrisDetector=None, k=None)
  • image:输入的灰度图像。

  • maxCorners:要检测的最大角点数量。如果检测到的角点数量超过该值,则会返回最强的角点。

  • qualityLevel:角点质量因子,用于筛选角点。值范围为0到1,表示最好的角点质量。

  • minDistance:两个角点之间的最小欧氏距离。如果两个角点之间的距离小于此值,则其中一个角点将被删除。

  • mask(可选):一个与输入图像大小相同的掩码图像,在掩码区域中不会检测到角点。

  • blockSize(可选):角点检测中使用的像素邻域大小。默认值为3。

  • useHarrisDetector(可选):一个布尔值,表示是否使用Harris角点检测器。默认为False,即使用Shi-Tomasi角点检测器。

  • k(可选):如果使用Harris角点检测器,此参数为Harris检测器的自由参数。默认值为0.04。

函数返回检测到的角点的坐标,以N x 1 x 2的Numpy数组形式返回。在返回的角点数组中,每个角点的坐标可以通过corner[0][0]corner[0][1]来访问。

注意:

cv2.goodFeaturesToTrack()函数只能用于灰度图像

1.2.2 OpenCV角点检测示例代码

OpenCV进行角点检测的示例代码:

python 复制代码
import cv2
import numpy as np

# 读取图像
img = cv2.imread("image.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 使用Shi-Tomasi角点检测
corners = cv2.goodFeaturesToTrack(gray, 100, 0.01, 10)
corners = np.int0(corners)

# 绘制角点
for corner in corners:
    x, y = corner.ravel()
    cv2.circle(img, (x, y), 3, (0, 0, 255), -1)

# 显示图像
cv2.imshow("Corners", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

首先读取图像并将其转换为灰度图像。使用cv2.goodFeaturesToTrack()函数进行角点检测,其中参数gray是输入灰度图像,100是要检测的角点数量,0.01是角点质量因子(0.01 * 最大特征值),10是两个角点之间的最小距离,函数返回的是检测到的角点坐标。

我们使用np.int0()将角点坐标转换为整数类型,并使用cv2.circle()函数绘制出检测到的角点。最后,使用cv2.imshow()显示带有角点的图像,并使用cv2.waitKey()等待键盘输入。

1.3 直线检测

1.3.1 cv2.HoughLinesP()函数

cv2.HoughLinesP()函数是OpenCV中用于通过Hough变换检测图像中的直线的函数。HoughLinesP()函数是Hough变换的参数空间的一种优化,它可以直接检测出图像中的直线的端点。

python 复制代码
 lines = cv2.HoughLinesP(image, rho, theta, threshold, minLineLength, maxLineGap)

参数解释:

  • image: 输入的二值图像。
  • rho: Hough变换中表示距离精度的参数。
  • theta: Hough变换中表示角度精度的参数。
  • threshold: Hough变换中表示直线的最小投票数。
  • minLineLength: 最小直线长度。
  • maxLineGap: 最大直线间隙。

返回值:

  • lines: 返回检测到的直线的起点和终点坐标。每个元素代表一条直线,每条直线由端点坐标组成。
1.3.2 OpenCV直线检测示例代码

在OpenCV中,可以使用Hough变换来进行直线检测。以下是使用OpenCV进行直线检测的示例代码:

python 复制代码
import cv2
import numpy as np

# 加载图像
image = cv2.imread('image.jpg')

# 转换为灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 进行边缘检测
edges = cv2.Canny(gray, 50, 150)

# 进行直线检测
lines = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=100, minLineLength=100, maxLineGap=10)

# 绘制检测到的直线
if lines is not None:
    for line in lines:
        x1, y1, x2, y2 = line[0]
        cv2.line(image, (x1, y1), (x2, y2), (0, 255, 0), thickness=2)

# 显示结果
cv2.imshow("Result", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

1.4 圆形检测

在OpenCV中进行圆形检测,可以使用Hough圆变换。Hough圆变换可以检测图像中的圆形轮廓。

1.4.1 cv2.HoughCircles()函数

使用cv2.HoughCircles()函数可以实现圆形检测。

python 复制代码
circles = cv2.HoughCircles(image, method, dp, minDist, param1, param2, minRadius, maxRadius)

参数解释:

  • image: 输入图像,通常为灰度图像。
  • method: Hough圆变换的检测方法,一般使用cv2.HOUGH_GRADIENT。
  • dp: 累加器图像分辨率与输入图像分辨率的倒数之比。通常设置为1。
  • minDist: 检测到的圆心之间的最小距离。
  • param1: 第一个方法特定的参数,对于HOUGH_GRADIENT方法,表示Canny边缘检测的高阈值。
  • param2: 第二个方法特定的参数,对于HOUGH_GRADIENT方法,表示检测阶段圆心累加器阈值。
  • minRadius: 最小圆形半径。
  • maxRadius: 最大圆形半径。

返回值:

  • circles: 返回检测到的圆形的圆心坐标和半径。
1.4.2 OpenCV圆形检测示例代码

在OpenCV中,可以使用Hough圆变换来进行直线检测。以下是使用OpenCV进行圆形检测的示例代码:

python 复制代码
import cv2
import numpy as np

image = cv2.imread('image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.medianBlur(gray, 5)

circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, dp=1, minDist=20, param1=50, param2=30, minRadius=0, maxRadius=0)

if circles is not None:
    circles = np.round(circles[0, :]).astype("int")
    for (x, y, r) in circles:
        cv2.circle(image, (x, y), r, (0, 255, 0), 4)

cv2.imshow('image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

以上示例代码中,首先读取图像并将其转换为灰度图像。然后对灰度图像进行中值滤波来去除噪声。接下来使用cv2.HoughCircles()函数检测图像中的圆形,并将检测到的圆形绘制在原图像上。最后显示原图像。

相关推荐
游客52016 分钟前
opencv中的各种滤波器简介
图像处理·人工智能·python·opencv·计算机视觉
小俊俊的博客20 分钟前
海康RGBD相机使用C++和Opencv采集图像记录
c++·opencv·海康·rgbd相机
KeyPan20 分钟前
【IMU:视觉惯性SLAM系统】
计算机视觉
7yewh21 分钟前
嵌入式Linux QT+OpenCV基于人脸识别的考勤系统 项目
linux·开发语言·arm开发·驱动开发·qt·opencv·嵌入式linux
Kai HVZ33 分钟前
《OpenCV计算机视觉》--介绍及基础操作
人工智能·opencv·计算机视觉
biter008838 分钟前
opencv(15) OpenCV背景减除器(Background Subtractors)学习
人工智能·opencv·学习
吃个糖糖44 分钟前
35 Opencv 亚像素角点检测
人工智能·opencv·计算机视觉
车轮滚滚__1 小时前
uniapp对接unipush 1.0 ios/android
笔记
云边有个稻草人4 小时前
【优选算法】—复写零(双指针算法)
笔记·算法·双指针算法
黑色叉腰丶大魔王5 小时前
基于 MATLAB 的图像增强技术分享
图像处理·人工智能·计算机视觉