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

运行结果:

相关推荐
海宇AI14 分钟前
零信任架构实战:基于海宇柠檬查出险-登记证构建自动化车抵贷核保网关
java·人工智能·架构·自动化
海带紫菜菠萝汤22 分钟前
大模型本地部署踩坑实录:显存不足、依赖冲突、推理慢的完整排查
人工智能·ai·大模型
斯维赤24 分钟前
AI Agent学习之路 | Prompt Engineering(提示词工程)的三板斧核心技巧
人工智能·学习·prompt
日常通勤穿搭1 小时前
电商 AI 生图工具横评|AI 生成主图、详情套图工具哪家性价比高
人工智能·aigc·电商美工
Ai_easygo2 小时前
AI下半场_06_CSDN版_开源AI最后一公里
人工智能
jimmyleeee2 小时前
大模型安全之十五:AI Access Control:当“门禁”遇上会思考的系统
人工智能·安全
HIT_Weston2 小时前
224、【AI】【模型部署】基座模型研究:Qwen2 架构总览与 config 对照
人工智能·模型部署
我叫张土豆2 小时前
本体论、DDD、SDD、TDD:AI 编程时代的四层认知栈
java·人工智能
蓝速科技2 小时前
便民服务大厅 AI 数字人一体机场景适配与落地指南丨蓝速科技
大数据·网络·数据结构·人工智能·自然语言处理·数据分析·运维开发