news 2026/5/10 2:21:50

计算机视觉--Opencv(郁金香图像轮廓提取与多边形逼近)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
计算机视觉--Opencv(郁金香图像轮廓提取与多边形逼近)

本次项目的核心目标有两个:

一是从郁金香图像中精准提取出整束花的外部原始轮廓,排除图像中的背景杂质与无关干扰;

二是通过多边形逼近算法对原始轮廓进行简化,得到平滑的近似轮廓,同时保留郁金香的核心形状特征。

代码如下:

1. 读取图像并预处理 img = cv2.imread(r"C:\Users\LEGION\Desktop\fb312a897160f2c9036096f52dbdecf6.png") # 转换为灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 二值化处理(针对白色背景郁金香,阈值240提升轮廓提取精度) _, thresh = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY_INV) # 2. 提取外部轮廓(OpenCV 3.x专属:返回3个值,下划线忽略无用的处理后图像) _, contours, hierarchy = cv2.findContours( thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE ) if len(contours) == 0: raise ValueError("未检测到图像轮廓,请调整二值化阈值或检查图像质量") # 选取面积最大的轮廓(确保是整束花的外部轮廓,排除杂质小轮廓) target_contour = max(contours, key=cv2.contourArea) # 3. 计算近似轮廓(ε=周长×0.005,符合题目要求) contour_perimeter = cv2.arcLength(target_contour, closed=True) epsilon = 0.005 * contour_perimeter approx_contour = cv2.approxPolyDP(target_contour, epsilon, closed=True) # 4. 核心:创建两个独立图像副本,分别绘制单一轮廓(避免叠加,实现分开输出) # 副本1:仅绘制红色原始外部轮廓 img_red_original = img.copy() cv2.drawContours( img_red_original, [target_contour], 0, (0, 0, 255), # OpenCV BGR格式:红色 2 # 线宽 ) # 副本2:仅绘制绿色近似轮廓 img_green_approx = img.copy() cv2.drawContours( img_green_approx, [approx_contour], 0, (0, 255, 0), # OpenCV BGR格式:绿色 2 # 线宽 ) # 5. 分开显示:两个独立窗口展示结果(可视化查看) # 窗口1:红色原始轮廓 cv2.namedWindow("Result 1: Red Original Contour", cv2.WINDOW_NORMAL) cv2.imshow("Result 1: Red Original Contour", img_red_original) # 窗口2:绿色近似轮廓 cv2.namedWindow("Result 2: Green Approx Contour", cv2.WINDOW_NORMAL) cv2.imshow("Result 2: Green Approx Contour", img_green_approx) # 6. 分开保存:两个独立文件持久化存储(可长期查看,保存在代码同级目录) cv2.imwrite('flower_red_original_contour.png', img_red_original) cv2.imwrite('flower_green_approx_contour.png', img_green_approx) # 打印保存提示 print("分开保存完成,文件路径:") print("1. 红色原始轮廓:flower_red_original_contour.png") print("2. 绿色近似轮廓:flower_green_approx_contour.png") # 等待按键输入后关闭所有显示窗口 cv2.waitKey(0) cv2.destroyAllWindows()

注释:

二值化处理:二值化处理是将灰度图像转换为只有黑色和白色两种像素值的图像,这样能够突出目标物体与背景的边界,方便后续轮廓提取。我们使用cv2.threshold()函数进行二值化处理,该函数有四个核心参数:

  • 第一个参数:待二值化的灰度图像(gray);

  • 第二个参数:阈值(240),本次实战中郁金香图像的背景是白色,像素值接近 255,郁金香本身的像素值低于 240,因此选择 240 作为阈值能够很好地区分郁金香和背景

  • 第三个参数:最大值(255),当像素值超过阈值(或低于阈值,取决于二值化类型)时,将其设置为该最大值;

  • 第四个参数:二值化类型(cv2.THRESH_BINARY_INV),表示反向二值化,即像素值低于阈值的设置为 255(白色),高于阈值的设置为 0(黑色)。这样处理后,郁金香会变成白色,背景会变成黑色,更符合 OpenCV 轮廓提取的要求。

cv2.findContours()函数有三个核心参数:

  • 第一个参数:二值化图像(thresh);

  • 第二个参数:轮廓检索模式(cv2.RETR_EXTERNAL),表示只提取最外层的轮廓,忽略内部的子轮廓,这正是我们需要的郁金香外部轮廓;

  • 第三个参数:轮廓逼近方法(cv2.CHAIN_APPROX_SIMPLE),表示压缩轮廓点,只保留轮廓的关键点(如直线的端点、曲线的拐点),能够大幅减少轮廓点的数量,节省内存空间。

运行结果:

(红色的为原始轮廓,绿色的为近似轮廓)

将两个图像的结果放在成同一张图上

代码如下:

'''郁金香图像的轮廓提取、轮廓近似(多边形逼近)- 结果合并在同一张图中''' import cv2 # 1. 读取图像并预处理 img = cv2.imread(r"C:\Users\LEGION\Desktop\fb312a897160f2c9036096f52dbdecf6.png") # 转换为灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 二值化处理(针对白色背景郁金香,阈值240提升轮廓提取精度) _, thresh = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY_INV) # 2. 提取外部轮廓(OpenCV 3.x专属:返回3个值,下划线忽略无用的处理后图像) _, contours, hierarchy = cv2.findContours( thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE ) if len(contours) == 0: raise ValueError("未检测到图像轮廓,请调整二值化阈值或检查图像质量") # 选取面积最大的轮廓(确保是整束花的外部轮廓,排除杂质小轮廓) target_contour = max(contours, key=cv2.contourArea) # 3. 计算近似轮廓(ε=周长×0.005,符合题目要求) contour_perimeter = cv2.arcLength(target_contour, closed=True) epsilon = 0.005 * contour_perimeter approx_contour = cv2.approxPolyDP(target_contour, epsilon, closed=True) # 4. 核心:创建单个图像副本,在同一张图上绘制两种轮廓(红色原始+绿色近似) img_combined = img.copy() # 仅创建一个图像副本,用于合并两种轮廓 # 先绘制红色原始外部轮廓 cv2.drawContours( img_combined, [target_contour], 0, (0, 0, 255), # OpenCV BGR格式:红色 2 # 线宽 ) # 再绘制绿色近似轮廓(在同一个副本上叠加绘制) cv2.drawContours( img_combined, [approx_contour], 0, (0, 255, 0), # OpenCV BGR格式:绿色 2 # 线宽 ) # 5. 可视化展示:单个窗口展示合并结果 cv2.namedWindow("Result: Red Original Contour + Green Approx Contour", cv2.WINDOW_NORMAL) cv2.imshow("Result: Red Original Contour + Green Approx Contour", img_combined) # 6. 保存结果:单个文件保存合并后的图像 cv2.imwrite('flower_combined_contours.png', img_combined) # 打印保存提示 print("合并结果保存完成,文件路径:") print("合并轮廓图像:flower_combined_contours.png") # 等待按键输入后关闭所有显示窗口 cv2.waitKey(0) cv2.destroyAllWindows()

轮廓叠加绘制:在img_combined上先调用cv2.drawContours()绘制红色原始轮廓,再调用一次该函数绘制绿色近似轮廓,OpenCV 会自动将两种轮廓叠加在同一张图上,红色和绿色对比清晰,能直观看到轮廓近似的简化效果。

运行结果:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/7 2:41:19

电机电磁振动噪声 NVH 的救星——Manatee 1.09

manatee电磁噪声振动计算softwareManatee 1.09 电机电磁振动噪声NVH终结者 带教程,带教程,带教程重要的话说3遍 史上最强后处理软件,甩jmag、Maxwell、flux几条街,极强的后处理,丰富图表,无需任何编程改写…

作者头像 李华
网站建设 2026/5/6 7:03:44

内存对齐与缓存友好设计

1、非修改序列算法 这些算法不会改变它们所操作的容器中的元素。 1.1 find 和 find_if find(begin, end, value):查找第一个等于 value 的元素,返回迭代器(未找到返回 end)。find_if(begin, end, predicate):查找第…

作者头像 李华
网站建设 2026/5/6 7:03:58

华为OD技术面真题 - 数据库MySQL - 2

文章目录 介绍一下MySQL查询语句执行过程简述一下MySQL的架构说一下你理解的数据库索引?分别说说索引的优点和缺点说说MySQL中索引类型?如何创建合适的索引?怎么优化查询速度 介绍一下MySQL查询语句执行过程 执行SQL查询语句会经过上述组件和…

作者头像 李华
网站建设 2026/5/5 18:27:45

自定义类型转换机制

1、非修改序列算法 这些算法不会改变它们所操作的容器中的元素。 1.1 find 和 find_if find(begin, end, value):查找第一个等于 value 的元素,返回迭代器(未找到返回 end)。find_if(begin, end, predicate):查找第…

作者头像 李华
网站建设 2026/5/8 19:42:36

Transformer 大模型架构深度解析(4)详解 Transformer 架构

目录 文章目录目录Transformer 架构Input EmbeddingPositional EncodingEncoder软对齐注意力的思想词向量相似度的计算方法Scaled Dot-Product AttentionSelf-AttentionMulti-Head Attention(Self-Attention)Feed Forward Neural NetworkResidual Connec…

作者头像 李华
网站建设 2026/5/7 16:39:40

‌别再手动对比日志了!AI日志分析工具实测TOP3

软件测试中的日志分析痛点‌ 在软件测试工作中,日志分析是核心环节,涉及错误追踪、性能监控和测试报告生成。传统手动方法耗时耗力:测试工程师需逐行比对日志文件,识别异常模式,平均每个项目消耗20-30小时。常见问题包…

作者头像 李华