Python OpenCV图像处理与深度学习:Python OpenCV边缘检测入门
本课程介绍图像边缘检测的基本概念及Canny算法的实现原理,包括噪声去除、梯度计算、非极大值抑制、双阈值检测和边缘跟踪五个关键步骤。通过Python和OpenCV库,演示了从读取图像到完整边缘检测的全过程,包括高斯滤波平滑图像、Sobel算子计算梯度、非极大值抑制细化边缘、双阈值确定真实边缘点以及边缘跟踪形成连续轮廓。课程结合理论讲解和代码实践,帮助学员掌握Canny这一经典边缘检测算法,并能够独
边缘检测:探索图像的轮廓
学习目标
通过本课程,学员们将掌握使用OpenCV进行边缘检测的基本方法,特别是Canny边缘检测算法的原理及其在Python中的实现。实验将通过理论讲解与实践操作相结合的方式,帮助学员理解边缘检测在图像处理中的重要性,并能够独立完成简单的边缘检测任务。
相关知识点
- Python OpenCV边缘检测
学习内容
1 Python OpenCV边缘检测
1.1 图像边缘检测的基本概念
图像边缘检测是图像处理和计算机视觉中的一个基本问题,它旨在从图像中提取出物体的轮廓信息。边缘通常定义为图像中亮度发生急剧变化的区域,这些变化可能是由于颜色、纹理或深度的不连续性引起的。边缘检测在许多应用中都非常重要,例如图像分割、特征提取、物体识别等。
边缘检测的基本原理是通过检测图像中像素值的梯度来识别边缘。梯度是一个向量,它指向函数值增加最快的方向,其大小表示变化的速率。在图像处理中,通常使用一阶导数(梯度)或二阶导数(拉普拉斯算子)来检测边缘。一阶导数检测边缘的位置,而二阶导数则可以用来确定边缘的精确位置。
1.2 Canny边缘检测算法原理
Canny边缘检测算法是John Canny在1986年提出的一种多级边缘检测算法,它被认为是边缘检测的“黄金标准”。Canny算法的目标是找到一个最优的边缘检测方法,该方法应该满足三个主要标准:好的检测、好的定位和唯一的响应。
- 好的检测:算法应该尽可能多地检测到图像中的实际边缘,同时尽量减少误检。
- 好的定位:检测到的边缘应该尽可能接近实际边缘的位置。
- 唯一的响应:算法应该尽量减少对单个边缘的重复检测。
Canny算法的步骤如下:
- 噪声去除:使用高斯滤波器平滑图像,以减少噪声对边缘检测的影响。
- 计算梯度强度和方向:使用Sobel算子计算图像中每个像素点的梯度强度和方向。
- 非极大值抑制:通过非极大值抑制来细化边缘,只保留局部最大值的像素点。
- 双阈值检测:使用两个阈值(高阈值和低阈值)来确定哪些边缘点是真正的边缘点。高于高阈值的点被认为是强边缘点,低于低阈值的点被丢弃,介于两者之间的点如果与强边缘点相连则被保留。
- 边缘跟踪:通过跟踪强边缘点来连接边缘,形成连续的边缘线。
1.3 使用OpenCV实现Canny边缘检测
在本课程中,将通过Python和OpenCV库来实现Canny边缘检测算法。首先,确保已经安装了OpenCV库,如果没有安装,可以使用以下命令进行安装:
%pip install opencv-python
接下来,编写一个简单的Python脚本来实现Canny边缘检测。使用一张示例图像,并逐步展示每个步骤的实现。
1.3.1 读取和显示图像
执行以下指令获取测试图片。
!wget https://model-community-picture.obs.cn-north-4.myhuaweicloud.com/ascend-zone/notebook_datasets/ec8bff622fa911f08e8ffa163edcddae/example.jpg
首先,需要读取一张图像并显示它。这一步骤确认图像已经正确加载。
import cv2
import matplotlib.pyplot as plt
import numpy as np
# 读取图像
image = cv2.imread('example.jpg', cv2.IMREAD_GRAYSCALE)
# 显示图像
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.show()
1.3.2 噪声去除
接下来,使用高斯滤波器对图像进行平滑处理,以减少噪声的影响。
# 应用高斯滤波器
blurred_image = cv2.GaussianBlur(image, (5, 5), 0)
# 显示平滑后的图像
plt.imshow(blurred_image, cmap='gray')
plt.title('Blurred Image')
plt.show()
1.3.3 计算梯度强度和方向
使用Sobel算子计算图像中每个像素点的梯度强度和方向。
# 计算梯度
sobelx = cv2.Sobel(blurred_image, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(blurred_image, cv2.CV_64F, 0, 1, ksize=3)
# 计算梯度强度和方向
gradient_magnitude = cv2.magnitude(sobelx, sobely)
gradient_direction = cv2.phase(sobelx, sobely, angleInDegrees=True)
# 显示梯度强度图像
plt.imshow(gradient_magnitude, cmap='gray')
plt.title('Gradient Magnitude')
plt.show()
1.3.4 非极大值抑制
通过非极大值抑制来细化边缘,只保留局部最大值的像素点。
# 非极大值抑制
def non_max_suppression(gradient_magnitude, gradient_direction):
height, width = gradient_magnitude.shape
suppressed = gradient_magnitude.copy()
for i in range(1, height - 1):
for j in range(1, width - 1):
angle = gradient_direction[i, j]
if (0 <= angle < 22.5) or (157.5 <= angle <= 180):
q = gradient_magnitude[i, j + 1]
r = gradient_magnitude[i, j - 1]
elif (22.5 <= angle < 67.5):
q = gradient_magnitude[i + 1, j - 1]
r = gradient_magnitude[i - 1, j + 1]
elif (67.5 <= angle < 112.5):
q = gradient_magnitude[i + 1, j]
r = gradient_magnitude[i - 1, j]
else:
q = gradient_magnitude[i - 1, j - 1]
r = gradient_magnitude[i + 1, j + 1]
if gradient_magnitude[i, j] < max(q, r):
suppressed[i, j] = 0
return suppressed
suppressed_image = non_max_suppression(gradient_magnitude, gradient_direction)
# 显示非极大值抑制后的图像
plt.imshow(suppressed_image, cmap='gray')
plt.title('Non-Max Suppression')
plt.show()
1.3.5 双阈值检测
使用两个阈值(高阈值和低阈值)来确定哪些边缘点是真正的边缘点。
# 双阈值检测
def double_threshold(suppressed, low_threshold, high_threshold):
strong_edge = 255
weak_edge = 50
thresholded = suppressed.copy()
strong_i, strong_j = np.where(thresholded >= high_threshold)
weak_i, weak_j = np.where((thresholded <= high_threshold) & (thresholded >= low_threshold))
thresholded[strong_i, strong_j] = strong_edge
thresholded[weak_i, weak_j] = weak_edge
thresholded[thresholded < low_threshold] = 0
return thresholded
thresholded_image = double_threshold(suppressed_image, 50, 150)
# 显示双阈值检测后的图像
plt.imshow(thresholded_image, cmap='gray')
plt.title('Double Threshold')
plt.show()
1.3.6 边缘跟踪
通过跟踪强边缘点来连接边缘,形成连续的边缘线。
# 边缘跟踪
def edge_tracking(thresholded):
strong_edge = 255
weak_edge = 50
edges = thresholded.copy()
for i in range(1, edges.shape[0] - 1):
for j in range(1, edges.shape[1] - 1):
if edges[i, j] == weak_edge:
if (edges[i + 1, j - 1] == strong_edge or
edges[i + 1, j] == strong_edge or
edges[i + 1, j + 1] == strong_edge or
edges[i, j - 1] == strong_edge or
edges[i, j + 1] == strong_edge or
edges[i - 1, j - 1] == strong_edge or
edges[i - 1, j] == strong_edge or
edges[i - 1, j + 1] == strong_edge):
edges[i, j] = strong_edge
else:
edges[i, j] = 0
return edges
final_edges = edge_tracking(thresholded_image)
# 显示最终的边缘检测结果
plt.imshow(final_edges, cmap='gray')
plt.title('Final Edges')
plt.show()

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)