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

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

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

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

代码如下:

python 复制代码
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),表示压缩轮廓点,只保留轮廓的关键点(如直线的端点、曲线的拐点),能够大幅减少轮廓点的数量,节省内存空间。

运行结果:

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

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

代码如下:

python 复制代码
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 会自动将两种轮廓叠加在同一张图上,红色和绿色对比清晰,能直观看到轮廓近似的简化效果。

运行结果:

相关推荐
星海之恋9922 小时前
比官方便宜一半以上!Midjourney API 申请及使用
人工智能·midjourney
机器学习算法与Python实战2 小时前
DeepSeek-OCR-2 本地部署,实测
人工智能·ocr
布谷鸟科技cookoo2 小时前
布谷鸟科技携AI边缘计算产品线亮相韩国ROSCon KOREA 2026
人工智能·科技·ai·边缘计算·交通物流
小雨青年2 小时前
鸿蒙 HarmonyOS 6 | AI Kit 集成 CANN Kit 异构计算服务
人工智能·华为·harmonyos
AI浩2 小时前
Python包离线下载
开发语言·人工智能·python·目标检测
草莓熊Lotso2 小时前
Qt 显示与输入类控件进阶:数字、进度、输入框实战攻略
java·大数据·开发语言·c++·人工智能·qt
心枢AI研习社2 小时前
数据库系列3——条件查询:把数据“筛对、排对”(WHERE/逻辑/范围/null/LIKE 一次讲透)
数据库·人工智能·oracle·aigc
jkyy20142 小时前
慢病智能管理+精准营销:健康有益赋能保健品行业价值重构
大数据·人工智能
azoo2 小时前
cv2.mean() 用于计算图像的像素值的平均值
人工智能·opencv·计算机视觉