当前位置: 首页 > news >正文

Python OpenCV图像处理与深度学习:Python OpenCV边缘检测入门

边缘检测:探索图像的轮廓

学习目标

通过本课程,学员们将掌握使用OpenCV进行边缘检测的基本方法,特别是Canny边缘检测算法的原理及其在Python中的实现。实验将通过理论讲解与实践操作相结合的方式,帮助学员理解边缘检测在图像处理中的重要性,并能够独立完成简单的边缘检测任务。

相关知识点

  • Python OpenCV边缘检测

学习内容

1 Python OpenCV边缘检测

1.1 图像边缘检测的基本概念

图像边缘检测是图像处理和计算机视觉中的一个基本问题,它旨在从图像中提取出物体的轮廓信息。边缘通常定义为图像中亮度发生急剧变化的区域,这些变化可能是由于颜色、纹理或深度的不连续性引起的。边缘检测在许多应用中都非常重要,例如图像分割、特征提取、物体识别等。

边缘检测的基本原理是通过检测图像中像素值的梯度来识别边缘。梯度是一个向量,它指向函数值增加最快的方向,其大小表示变化的速率。在图像处理中,通常使用一阶导数(梯度)或二阶导数(拉普拉斯算子)来检测边缘。一阶导数检测边缘的位置,而二阶导数则可以用来确定边缘的精确位置。

1.2 Canny边缘检测算法原理

Canny边缘检测算法是John Canny在1986年提出的一种多级边缘检测算法,它被认为是边缘检测的“黄金标准”。Canny算法的目标是找到一个最优的边缘检测方法,该方法应该满足三个主要标准:好的检测、好的定位和唯一的响应。

  • 好的检测:算法应该尽可能多地检测到图像中的实际边缘,同时尽量减少误检。
  • 好的定位:检测到的边缘应该尽可能接近实际边缘的位置。
  • 唯一的响应:算法应该尽量减少对单个边缘的重复检测。

Canny算法的步骤如下:

  1. 噪声去除:使用高斯滤波器平滑图像,以减少噪声对边缘检测的影响。
  2. 计算梯度强度和方向:使用Sobel算子计算图像中每个像素点的梯度强度和方向。
  3. 非极大值抑制:通过非极大值抑制来细化边缘,只保留局部最大值的像素点。
  4. 双阈值检测:使用两个阈值(高阈值和低阈值)来确定哪些边缘点是真正的边缘点。高于高阈值的点被认为是强边缘点,低于低阈值的点被丢弃,介于两者之间的点如果与强边缘点相连则被保留。
  5. 边缘跟踪:通过跟踪强边缘点来连接边缘,形成连续的边缘线。
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.shapesuppressed = 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] = 0return suppressedsuppressed_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 = 255weak_edge = 50thresholded = 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_edgethresholded[weak_i, weak_j] = weak_edgethresholded[thresholded < low_threshold] = 0return thresholdedthresholded_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 = 255weak_edge = 50edges = 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 oredges[i + 1, j] == strong_edge oredges[i + 1, j + 1] == strong_edge oredges[i, j - 1] == strong_edge oredges[i, j + 1] == strong_edge oredges[i - 1, j - 1] == strong_edge oredges[i - 1, j] == strong_edge oredges[i - 1, j + 1] == strong_edge):edges[i, j] = strong_edgeelse:edges[i, j] = 0return edgesfinal_edges = edge_tracking(thresholded_image)
# 显示最终的边缘检测结果
plt.imshow(final_edges, cmap='gray')
plt.title('Final Edges')
plt.show()

在这里插入图片描述

http://www.dtcms.com/a/362201.html

相关文章:

  • FastLED库完全指南:打造炫酷LED灯光效果
  • 【Excel】将一个单元格内​​的多行文本,​​拆分成多个单元格,每个单元格一行​​
  • 【设计模式】--重点知识点总结
  • C++ Bellman-Ford算法
  • Linux并发与竞争实验
  • 软件使用教程(四):Jupyter Notebook 终极使用指南
  • 数据分析编程第八步:文本处理
  • 设计模式-状态模式 Java
  • 华清远见25072班I/O学习day2
  • PostgreSQL备份指南:逻辑与物理备份详解
  • 椭圆曲线群运算与困难问题
  • 【数据分享】多份土地利用矢量shp数据分享-澳门
  • AI产品经理面试宝典第81天:RAG系统架构演进与面试核心要点解析
  • Qt中的信号与槽机制的主要优点
  • 自动化测试时,chrome浏览器启动后闪退的问题
  • 【趣味阅读】Python 文件头的秘密:从编码声明到 Shebang
  • VisionProC#联合编程相机实战开发
  • 【云存储桶安全】怎么满足业务需求,又最大程度上满足信息安全要求呢?
  • 1792. 最大平均通过率
  • 学习:uniapp全栈微信小程序vue3后台-暂时停更
  • 本地没有公网ip?用cloudflare部署内网穿透服务器,随时随地用自定义域名访问自己应用端口资源
  • 液态神经网络:智能制造的新引擎
  • 【跨境电商】上中下游解释,以宠物行业为例
  • 洛谷 c++ P1177 【模板】排序 题解
  • AutoSar RTE介绍
  • 特征增强方法【特征构建】
  • MVC、三层架构
  • RT-DETR网络结构
  • 并发之线程
  • 【思考】WSL是什么