基于OpenCV的图像边缘检测与轮廓分析

 更新时间:2026年01月19日 08:23:01   作者:子夜江寒  
本文介绍了图像处理中的边缘检测和轮廓分析方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、边缘检测方法

1. Sobel算子边缘检测

Sobel算子通过计算图像灰度函数的梯度来检测边缘,分别计算水平和垂直方向的梯度,然后合并得到完整边缘图像。

import cv2

pic = cv2.imread(r"picture_1.jpg", 0)
pic_x_64 = cv2.Sobel(pic, cv2.CV_64F, dx=1, dy=0)
pic_x_full = cv2.convertScaleAbs(pic_x_64)
pic_y_64 = cv2.Sobel(pic, cv2.CV_64F, dx=0, dy=1)
pic_y_full = cv2.convertScaleAbs(pic_y_64)
pic_xy_sobel_full = cv2.addWeighted(pic_x_full, 1, pic_y_full, 1, 0)

参数分析:

  • cv2.CV_64F:输出图像的深度,64位浮点数类型
  • dx=1, dy=0:计算x方向(水平)梯度
  • dx=0, dy=1:计算y方向(垂直)梯度
  • cv2.convertScaleAbs():将负梯度值转换为绝对值并缩放

2. Scharr算子边缘检测

Scharr算子是Sobel算子的改进版本,对边缘的响应更敏感,能检测到更细微的边缘变化。

pic = cv2.imread(r"picture_1.jpg", cv2.IMREAD_GRAYSCALE)
pic_x_64 = cv2.Scharr(pic, cv2.CV_64F, dx=1, dy=0)
pic_x_full = cv2.convertScaleAbs(pic_x_64)
pic_y_64 = cv2.Scharr(pic, cv2.CV_64F, dx=0, dy=1)
pic_y_full = cv2.convertScaleAbs(pic_y_64)
pic_xy_scharr_full = cv2.addWeighted(pic_x_full, 1, pic_y_full, 1, 0)

3. Laplacian边缘检测

Laplacian算子基于二阶导数,能同时检测图像的两个方向的边缘,对噪声更敏感但能检测到更精细的边缘。

pic = cv2.imread(r"picture_1.jpg", cv2.IMREAD_GRAYSCALE)
pic_lap = cv2.Laplacian(pic, cv2.CV_64F, ksize=3)
pic_lap_full = cv2.convertScaleAbs(pic_lap)

参数分析:

  • ksize=3:拉普拉斯核的大小,必须为正奇数

4. Canny边缘检测

Canny边缘检测是多阶段算法,包括高斯滤波、梯度计算、非极大值抑制和双阈值检测,是效果最好的边缘检测算法之一。

pic = cv2.imread(r"picture_1.jpg", cv2.IMREAD_GRAYSCALE)
pic_canny = cv2.Canny(pic, 100, 150)

参数分析:

  • 100:低阈值,低于此值的边缘被丢弃
  • 150:高阈值,高于此值的边缘被保留为强边缘

二、图像轮廓分析

1. 轮廓提取基础

轮廓提取需要先将图像转换为二值图像,然后使用findContours函数查找轮廓。

# 灰度图处理
phone = cv2.imread(r"picture_1.jpg")
phone = cv2.resize(phone, dsize=None, fx=0.4, fy=0.4)
phone_gray = cv2.cvtColor(phone, cv2.COLOR_BGR2GRAY)

# 阈值处理为二值图像
ret, phone_binary = cv2.threshold(phone_gray, 120, 255, cv2.THRESH_BINARY)

# 查找轮廓
_, contours, hierarchy = cv2.findContours(phone_binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

print(len(contours))

参数分析:

  • cv2.THRESH_BINARY:阈值化类型,大于阈值设为255,小于设为0
  • cv2.RETR_TREE:轮廓检索模式,检索所有轮廓并重建完整的层次结构
  • cv2.CHAIN_APPROX_NONE:轮廓近似方法,存储所有轮廓点

2. 轮廓绘制方法

image_copy = phone.copy()
cv2.drawContours(image=image_copy, contours=contours, contourIdx=-1, color=(0, 255, 0), thickness=2)

# 逐个绘制轮廓的替代方法
for i in range(len(contours)):
    image_copy = cv2.drawContours(image=image_copy, contours=contours, contourIdx=i, color=(0, 255, 0), thickness=3)
    cv2.imshow('Contours_show', image_copy)
    cv2.waitKey(0)

参数分析:

contourIdx=-1:绘制所有轮廓,指定索引则绘制单个轮廓

3. 轮廓特征计算

# 轮廓面积计算
area_0 = cv2.contourArea(contours[0])
area_1 = cv2.contourArea(contours[1])

# 轮廓周长计算
length = cv2.arcLength(contours[0], closed=True)

# 根据面积筛选轮廓
a_list = []
for i in contours:
    if cv2.contourArea(i) > 10000:
        a_list.append(i)

4. 轮廓定位与排序

# 根据面积排序获取最大轮廓
sortcnt = sorted(contours, key=cv2.contourArea, reverse=True)[0]
image_contours = cv2.drawContours(image_copy, [sortcnt], contourIdx=-1, color=(0, 0, 255), thickness=3)

5. 轮廓几何特征

cnt = contours[8]

# 最小外接圆
(x, y), r = cv2.minEnclosingCircle(cnt)
phone_circle = cv2.circle(phone, center=(int(x), int(y)), radius=int(r), color=(0, 255, 0), thickness=2)

# 最小外接矩形
x, y, w, h = cv2.boundingRect(cnt)
phone_rectangle = cv2.rectangle(phone, pt1=(x, y), pt2=(x + w, y + h), color=(0, 255, 0), thickness=2)

三、轮廓近似与简化

轮廓近似可以减少轮廓点的数量,同时保持轮廓的基本形状,常用于减少计算复杂度和数据存储。

phone = cv2.imread('phone.png')
phone_gray = cv2.cvtColor(phone, cv2.COLOR_BGR2GRAY)
ret, phone_thresh = cv2.threshold(phone_gray, 120, 255, cv2.THRESH_BINARY)

# 兼容不同OpenCV版本的轮廓查找
contours = cv2.findContours(phone_thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[-2]

# 轮廓近似
epsilon = 0.01 * cv2.arcLength(contours[0], closed=True)
approx = cv2.approxPolyDP(contours[0], epsilon, closed=True)

print(contours[0].shape)  # 原始轮廓点数
print(approx.shape)       # 近似后轮廓点数

# 绘制近似轮廓
phone_new = phone.copy()
image_contours = cv2.drawContours(phone_new, [approx], contourIdx=-1, color=(0, 255, 0), thickness=3)

参数分析:

  • epsilon:近似精度参数,通常取轮廓周长的百分比
  • closed=True:指示轮廓是封闭的

到此这篇关于基于OpenCV的图像边缘检测与轮廓分析的文章就介绍到这了,更多相关OpenCV 图像边缘检测与轮廓内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python实现Excel条件格式自动化设置

    Python实现Excel条件格式自动化设置

    在处理大量 Excel 数据时,条件格式无疑是提升数据可读性和洞察力的强大工具,本文将深入探讨如何利用 Python 及其 Spire.XLS for Python 库,实现 Excel 条件格式的自动化设置,感兴趣的小伙伴可以了解下
    2026-01-01
  • python如何打印杨辉三角及输出第m行第k个数

    python如何打印杨辉三角及输出第m行第k个数

    这篇文章主要介绍了python如何打印杨辉三角及输出第m行第k个数问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • 详解Python发送email的三种方式

    详解Python发送email的三种方式

    这篇文章主要介绍了详解Python发送email的三种方式,Python发送email的三种方式,分别为使用登录邮件服务器、使用smtp服务、调用sendmail命令来发送三种方法,非常具有实用价值,需要的朋友可以参考下
    2018-10-10
  • Python编解码问题及文本文件处理方法详解

    Python编解码问题及文本文件处理方法详解

    最近在做一个项目,因为文本处理的内容是中文,所以不得不面对python中文处理所带来的种种困惑,这篇文章主要给大家介绍了关于Python编解码问题及文本文件处理方法的相关资料,需要的朋友可以参考下
    2021-06-06
  • Python中SyntaxError: invalid syntax报错解决

    Python中SyntaxError: invalid syntax报错解决

    在编写Python代码时,常见的SyntaxError错误通常由括号不匹配、关键字拼写错误或不正确的缩进引起,本文详细介绍了错误原因及多种解决方案,包括检查括号、关键字,以及使用IDE的语法检查功能等,感兴趣的可以了解一下
    2024-09-09
  • OpenCV实现图像滤波之双边滤波

    OpenCV实现图像滤波之双边滤波

    这篇文章主要为大家详细介绍了OpenCV实现图像滤波之双边滤波,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • Django显示可视化图表的实践

    Django显示可视化图表的实践

    这篇文章主要介绍了Django显示可视化图表的实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • python按行读取文件并找出其中指定字符串

    python按行读取文件并找出其中指定字符串

    这篇文章主要介绍了python按行读取文件并找出其中指定字符串的方法,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08
  • Python桌面应用开发实战之PyQt的安装使用

    Python桌面应用开发实战之PyQt的安装使用

    这篇文章主要给大家介绍了关于Python桌面应用开发实战之PyQt的安装使用,PyQt是一个功能强大的Python库,用于创建图形用户界面(GUI)应用程序,需要的朋友可以参考下
    2023-08-08
  • python实现智能语音天气预报

    python实现智能语音天气预报

    今天小编就为大家分享一篇python实现智能语音天气预报,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12

最新评论