在计算机视觉领域,OpenCV 是一款功能强大且应用广泛的开源库,它提供了丰富的 API,支持图像读取、预处理、特征检测等多种操作。本文将结合实际代码案例,详细讲解如何使用 OpenCV 实现轮廓检测、轮廓近似、模板匹配等常用功能,同时介绍如何通过argparse模块配置命令行参数,让程序更具灵活性和可扩展性。

一、OpenCV 图像处理核心功能实战

(一)图像轮廓检测与筛选

轮廓是图像中物体边界的重要表示,通过检测轮廓,我们可以获取物体的形状、大小等关键信息。以下代码实现了从图像读取、预处理到轮廓检测、筛选与绘制的完整流程。

import cv2# 1. 读取图像并进行预处理
phone = cv2.imread('lunkuo.png')  # 替换为你的图片路径
# 转为灰度图,减少计算量并为后续二值化做准备
gray = cv2.cvtColor(phone, cv2.COLOR_BGR2GRAY)
# 二值化处理:将灰度图转为黑白二值图,突出物体轮廓
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)# 2. 检测轮廓(兼容OpenCV 3.x和4.x版本)
img, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# 3. 计算轮廓的面积与周长
# 计算前两个轮廓的面积
area_0 = cv2.contourArea(contours[0])
print(f"第一个轮廓的面积:{area_0}")
area_1 = cv2.contourArea(contours[1])
print(f"第二个轮廓的面积:{area_1}")
# 计算第一个轮廓的周长(closed=True表示轮廓是闭合的)
length = cv2.arcLength(contours[0], closed=True)
print(f"第一个轮廓的周长:{length}")# 4. 筛选面积大于10000的轮廓(去除小噪声轮廓)
filtered_contours = []
for contour in contours:if cv2.contourArea(contour) > 10000:filtered_contours.append(contour)
# 绘制筛选后的轮廓(绿色,线宽3)
image_copy = phone.copy()
cv2.drawContours(image=image_copy, contours=filtered_contours,contourIdx=-1, color=(0, 255, 0), thickness=3)
cv2.imshow('Contours_show_10000', image_copy)
cv2.waitKey(0)  # 等待按键,按下任意键关闭窗口# 5. 找到面积最大的轮廓并绘制(红色,线宽3)
# 按面积降序排序轮廓
sorted_contours = sorted(contours, key=cv2.contourArea, reverse=True)
largest_contour = sorted_contours[0]
# 绘制最大轮廓
image_copy = phone.copy()
cv2.drawContours(image=image_copy, contours=[largest_contour],contourIdx=-1, color=(0, 0, 255), thickness=3)
cv2.imshow('largest_contour', image_copy)
cv2.waitKey(0)# 6. 为指定轮廓绘制外接圆和外接矩形
cnt = contours[2]  # 选择第三个轮廓(可根据实际需求调整索引)
# 绘制外接圆(绿色,线宽2)
(x, y), radius = cv2.minEnclosingCircle(cnt)
center = (int(x), int(y))  # 圆心坐标(需转为整数,图像像素坐标为整数)
phone_circle = cv2.circle(phone, center, int(radius), (0, 255, 0), 2)
cv2.imshow('phone_circle', phone_circle)
cv2.waitKey(0)
# 绘制外接矩形(绿色,线宽2)
x, y, w, h = cv2.boundingRect(cnt)  # x,y为矩形左上角坐标,w为宽,h为高
phone_rectangle = cv2.rectangle(phone, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow('phone_rectangle', phone_rectangle)
cv2.waitKey(0)cv2.destroyAllWindows()  # 关闭所有OpenCV窗口

关键知识点解析

  • 图像预处理cvtColor将 BGR 格式(OpenCV 默认读取格式)转为灰度图,threshold通过设定阈值(此处为 127)将灰度图转为二值图,让轮廓更清晰。
  • 轮廓检测findContours函数中,RETR_TREE表示获取轮廓的层级关系,CHAIN_APPROX_SIMPLE会简化轮廓,去除冗余点,减少内存占用。
  • 轮廓筛选与排序:通过contourArea计算轮廓面积,结合条件判断筛选出目标轮廓;sorted函数配合cv2.contourArea可按面积对轮廓排序,轻松找到最大轮廓。

(二)轮廓近似:简化复杂轮廓

当轮廓边缘过于复杂(如包含大量细小锯齿)时,我们可以通过轮廓近似算法,用更少的点表示轮廓,同时保留其整体形状。以下代码演示了轮廓近似的实现过程:

import cv2# 1. 读取图像并预处理(步骤与上一部分类似)
phone = cv2.imread('lunkuo.png')
gray = cv2.cvtColor(phone, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)# 2. 检测轮廓(兼容不同OpenCV版本,取返回值的后两个元素)
contours = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[-2]# 3. 轮廓近似
# epsilon为近似精度,是轮廓周长的百分比(此处为1%),值越小,近似轮廓越接近原轮廓
epsilon = 0.01 * cv2.arcLength(contours[0], True)
# approxPolyDP函数实现轮廓近似,True表示轮廓闭合
approx = cv2.approxPolyDP(contours[0], epsilon, True)# 4. 对比原轮廓与近似轮廓的形状(输出点的数量)
print(f"原轮廓的点数量:{contours[0].shape}")  # 格式为(N, 1, 2),N为点的数量
print(f"近似轮廓的点数量:{approx.shape}")# 5. 绘制近似轮廓并显示
phone_new = phone.copy()
image_contours = cv2.drawContours(phone_new, [approx], contourIdx=-1, color=(0, 255, 0), thickness=3)
cv2.imshow('原始图像', phone)
cv2.waitKey(0)
cv2.imshow('近似轮廓', image_contours)
cv2.waitKey(0)
cv2.destroyAllWindows()

核心原理:轮廓近似基于Douglas-Peucker 算法,通过设定epsilon值控制近似程度。epsilon越小,近似轮廓与原轮廓的差异越小,但点的数量越多;epsilon越大,轮廓越简化,但可能丢失细节。实际应用中需根据需求调整该参数。

(三)模板匹配:在图像中查找目标物体

模板匹配是通过滑动模板图像在待检测图像上移动,计算模板与待检测图像各区域的相似度,从而找到目标物体位置的技术。以下代码实现了在 “可乐” 图像中查找 “瓶盖” 模板的功能:

import cv2# 1. 读取待检测图像(kele.png)和模板图像(keke.png)
kele = cv2.imread('kele.png')
keke = cv2.imread('keke.png')# 2. 显示原始图像,确认图像读取成功
cv2.imshow('可乐图像', kele)
cv2.imshow('瓶盖模板', keke)
cv2.waitKey(0)# 3. 获取模板图像的高和宽(用于后续绘制矩形)
h, w = keke.shape[:2]  # shape返回(高, 宽, 通道数),取前两个元素# 4. 执行模板匹配
# 匹配方法:cv2.TM_CCORR_NORMED(归一化相关匹配),返回相似度矩阵
res = cv2.matchTemplate(kele, keke, cv2.TM_CCORR_NORMED)# 5. 找到相似度最高的位置(归一化匹配中,最大值对应最相似区域)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
top_left = max_loc  # 匹配区域的左上角坐标
bottom_right = (top_left[0] + w, top_left[1] + h)  # 匹配区域的右下角坐标# 6. 在待检测图像上绘制矩形框,标记目标位置(绿色,线宽2)
kele_keke = cv2.rectangle(kele, top_left, bottom_right, (0, 255, 0), 2)# 7. 显示匹配结果
cv2.imshow('模板匹配结果', kele_keke)
cv2.waitKey(0)
cv2.destroyAllWindows()

注意事项

  • 模板匹配对尺度和旋转敏感,如果目标物体在待检测图像中发生缩放或旋转,匹配效果会显著下降,此时需结合尺度不变特征变换(SIFT)、旋转不变特征变换(SURF)等算法。
  • 匹配方法的选择:除TM_CCORR_NORMED外,OpenCV 还提供TM_SQDIFF(平方差匹配,最小值为最佳匹配)、TM_CCOEFF(相关系数匹配)等方法,需根据实际场景选择。

二、用 argparse 配置命令行参数,提升程序灵活性

在实际项目中,我们常需要调整程序参数(如阈值、端口号等),如果每次修改都直接改动代码,效率较低。argparse是 Python 标准库中的模块,可实现命令行参数的解析,让参数配置更便捷。以下代码演示了其基本用法:

import argparse# 1. 创建参数解析器对象
parser = argparse.ArgumentParser(description='命令行参数配置示例')  # description为程序描述# 2. 添加命令行参数
# --SERIAL_PORT1:第一个报警器的串口号,字符串类型,默认值为COM5,help为参数说明
parser.add_argument('--SERIAL_PORT1', type=str, default='COM5', help='第一个报警器的串口号')
# --area_thred:物体面积阈值,整数类型,默认值1600
parser.add_argument('--area_thred', type=int, default=1600, help='物体面积的阈值')
# --confid_level:识别置信度,浮点类型,默认值0.8
parser.add_argument('--confid_level', type=float, default=0.8, help='识别的置信度')
# --aaa:自定义整数参数,默认值100(无短选项)
parser.add_argument('--aaa', type=int, default=100)
# -b/--bbb:自定义整数参数,支持短选项(-b)和长选项(--bbb),默认值10
parser.add_argument('-b', '--bbb', type=int, default=10)# 3. 解析命令行参数
opt = parser.parse_args()# 4. 使用解析后的参数
a = opt.aaa
b = opt.bbb
print(f"参数aaa与bbb的和为:{a + b}")

使用方法

  1. 将代码保存为argparse_demo.py
  2. 在命令行中运行,可直接使用默认参数:

    bash

    python argparse_demo.py
    

    输出:参数aaa与bbb的和为:110
  3. 也可在命令行中指定参数值,覆盖默认值:

    bash

    python argparse_demo.py --aaa 200 -b 50 --SERIAL_PORT1 COM3 --area_thred 2000
    

    输出:参数aaa与bbb的和为:250

优势:通过argparse,我们无需修改代码,即可在命令行中灵活调整参数,尤其适合批量运行程序或在服务器环境中使用。

三、总结与拓展

本文通过实际代码案例,讲解了 OpenCV 中轮廓检测、轮廓近似、模板匹配等核心功能的实现,同时介绍了argparse模块的使用,帮助提升程序的灵活性。这些技术在目标检测、图像分割、物体识别等场景中应用广泛,例如:

  • 工业质检:通过轮廓检测判断产品是否存在缺陷。
  • 智能监控:通过模板匹配查找特定目标(如可疑物品)。
  • 机器人视觉:通过轮廓近似简化物体形状,便于机器人抓取。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/95359.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/95359.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/95359.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习---pytorch卷积神经网络保存和使用最优模型

在深度学习模型训练过程中,如何提升模型性能、精准保存最优模型并实现高效推理,是每个开发者必须攻克的关键环节。本文结合实际项目经验与完整代码示例,详细拆解模型训练优化、最优模型保存与加载、图像预测全流程,帮助大家避开常…

FPGA实现Aurora 64B66B图像视频点对点传输,基于GTY高速收发器,提供2套工程源码和技术支持

目录 1、前言Aurora 64B66B是啥?官方有Example,为何要用你这个?工程概述免责声明 2、相关方案推荐我已有的所有工程源码总目录----方便你快速找到自己喜欢的项目我这里已有的 GT 高速接口解决方案本方案在Aurora 8B10B上的应用 3、工程详细设…

LeetCode 524.通过删除字母匹配到字典里最长单词

给你一个字符串 s 和一个字符串数组 dictionary ,找出并返回 dictionary 中最长的字符串,该字符串可以通过删除 s 中的某些字符得到。 如果答案不止一个,返回长度最长且字母序最小的字符串。如果答案不存在,则返回空字符串。 示例…

kali_linux

【2024版】最新kali linux入门及常用简单工具介绍(非常详细)从零基础入门到精通,看完这一篇就够了-CSDN博客

MyBatis 常见错误与解决方案:从坑中爬出的实战指南

🔍 MyBatis 常见错误与解决方案:从坑中爬出的实战指南 文章目录🔍 MyBatis 常见错误与解决方案:从坑中爬出的实战指南🐛 一、N1 查询问题与性能优化💡 什么是 N1 查询问题?⚠️ 错误示例✅ 解决…

蓝牙modem端frequency offset compensation算法描述

蓝牙Modem中一个非常关键的算法:频偏估计与补偿(Frequency Offset Estimation and Compensation)。这个算法是接收机(解调端)能正确工作的基石。 我将为您详细解释这个算法的原理、必要性以及其工作流程。 一、核心问题:为什么需要频偏补偿? 频偏的来源: 如第一张图所…

基于STM32的居家养老健康安全检测系统

若该文为原创文章,转载请注明原文出处。一、 项目背景与立项意义社会老龄化趋势加剧:全球范围内,人口结构正经历着前所未有的老龄化转变。中国也不例外,正快速步入深度老龄化社会。随之而来的是庞大的独居、空巢老年人群体的健康监…

简易TCP网络程序

目录 1. TCP 和 UDP 的基本区别 2. TCP 中的 listen、accept 和 connect 3. UDP 中的区别:没有 listen、accept 和 connect 4. 总结对比: 2.字符串回响 2.1.核心功能 2.2 代码展示 1. server.hpp 服务器头文件 2. server.cpp 服务器源文件 3. …

广电手机卡到底好不好?

中国广电于2020年与中国移动签署了战略合作协议,双方在5G基站建设方面实现了共建共享。直到2022年下半年,中国广电才正式进入号卡服务领域,成为新晋运营商。虽然在三年的时间内其发展速度较快,但对于消费者而言,广电的…

Git中批量恢复文件到之前提交状态

<摘要> Git中批量恢复文件到之前提交状态的核心命令是git checkout、git reset和git restore。根据文件是否已暂存&#xff08;git add&#xff09;&#xff0c;需采用不同方案&#xff1a;未暂存变更用git checkout -- <file>或git restore <file>丢弃修改&…

UniApp 基础开发第一步:HBuilderX 安装与环境配置

UniApp 是一个基于 Vue.js 的跨平台开发框架&#xff0c;支持快速构建小程序、H5、App 等应用。作为开发的第一步&#xff0c;正确安装和配置 HBuilderX&#xff08;官方推荐的 IDE&#xff09;是至关重要的。下面我将以清晰步骤引导您完成整个过程&#xff0c;确保环境可用。整…

华为云Stack Deploy安装(VMware workstation物理部署)

1.1 华为云Stack Deploy安装(VMware workstation物理部署) 步骤 1 安装软件及环境准备 HUAWEI_CLOUD_Stack_Deploy_8.1.1-X86_64.iso HCSD安装镜像 VMware workstation软件 VirtualBox安装包 步骤2 修改VMware workstation网络模式 打开VMware workstation软件,点“编辑”…

安全等保复习笔记

信息安全概述1.2 信息安全的脆弱性及常见安全攻击 • 网络环境的开放性物理层--物理攻击 • 物理设备破坏 ➢ 指攻击者直接破坏网络的各种物理设施&#xff0c;比如服务器设施&#xff0c;或者网络的传输通信设施等 ➢ 设备破坏攻击的目的主要是为了中断网络服务 • 物理设备窃…

【Audio】切换至静音或振动模式时媒体音自动置 0

一、问题描述 基于 Android 14平台&#xff0c;AudioService 中当用户切换到静音模式&#xff08;RINGER_MODE_SILENT&#xff09;或振动模式&#xff08;RINGER_MODE_VIBRATE&#xff09;时会自动将响铃和通知音量置0&#xff0c;当切换成响铃模式&#xff08;RINGER_MODE_NO…

VPS云服务器安全加固指南:从入门到精通的全面防护策略

在数字化时代&#xff0c; VPS云服务器已成为企业及个人用户的重要基础设施。随着网络攻击手段的不断升级&#xff0c;如何有效进行VPS安全加固成为每个管理员必须掌握的技能。本文将系统性地介绍从基础配置到高级防护的完整安全方案&#xff0c;帮助您构建铜墙铁壁般的云服务器…

Mysql杂志(八)

游标游标是MySQL中一种重要的数据库操作机制&#xff0c;它解决了SQL集合操作与逐行处理之间的矛盾。这个相信大家基本上都怎么使用过&#xff0c;这个都是建立在使用存储过程的基础上的。我们都知道SQL都是批量处理的也就是面向集合操作&#xff08;一次操作多行&#xff09;&…

Dify 从入门到精通(第 71/100 篇):Dify 的实时流式处理(高级篇)

Dify 从入门到精通&#xff08;第 71/100 篇&#xff09;&#xff1a;Dify 的实时流式处理 Dify 入门到精通系列文章目录 第一篇《Dify 究竟是什么&#xff1f;真能开启低代码 AI 应用开发的未来&#xff1f;》介绍了 Dify 的定位与优势第二篇《Dify 的核心组件&#xff1a;从…

日志分析与安全数据上传脚本

最近在学习计算机网络&#xff0c;想着跟python结合做一些事情。这段代码是一个自动化脚本&#xff0c;它主要有三个功能&#xff1a;分析日志&#xff1a; 它从你指定的日志文件中读取内容&#xff0c;并筛选出所有包含特定关键字的行。网络交互&#xff1a; 它将筛选出的数据…

【论文阅读】Sparse4D v3:Advancing End-to-End 3D Detection and Tracking

标题&#xff1a;Sparse4D v3&#xff1a;Advancing End-to-End 3D Detection and Tracking 作者&#xff1a;Xuewu Lin, Zixiang Pei, Tianwei Lin, Lichao Huang, Zhizhong Su motivation 作者觉得做自动驾驶&#xff0c;还需要跟踪。于是更深入的把3D-检测&跟踪用sparse…

基于 DNA 的原核生物与微小真核生物分类学:分子革命下的范式重构​

李升伟 李昱均 茅 矛&#xff08;特趣生物科技公司&#xff0c;email: 1298261062qq.com&#xff09;传统微生物分类学长期依赖形态特征和生理生化特性&#xff0c;这在原核生物和微小真核生物研究中面临巨大挑战。原核生物形态简单且表型可塑性强&#xff0c;微小真核生物…