文章目录

    • 概要
    • 整体架构流程
    • 技术名词解释
    • 技术细节
      • 1. 多阈值适配与目标识别逻辑
      • 2. 动态ROI与状态管理机制
      • 3. 数据平滑与偏差计算
      • 4. 硬件适配与UART通信
    • 小结
  • 静态矩形框识别
  • 动态矩形框追踪

概要

本文分析的代码是基于立创·庐山派K230CanMV开发板的目标追踪系统实现,主要功能是通过GC2093传感器采集图像,识别特定"黑框白心"目标(如带黑色边框的白色标记物),计算目标位置偏差并通过UART串口发送数据,同时在显示器(虚拟窗口、LCD或HDMI)上实时展示追踪过程及调试信息。

整体架构流程

代码整体遵循"初始化-循环处理-资源释放"的经典嵌入式系统流程,具体步骤如下:

  1. 系统初始化

    • 硬件配置:初始化FPIOA引脚映射,配置UART2(波特率115200)用于数据传输。
    • 传感器初始化:启动GC2093传感器,设置分辨率(400x240)和灰度模式,开始采集图像。
    • 显示器初始化:根据DISPLAY_MODE(VIRT/LCD/HDMI)初始化对应显示设备,设置显示分辨率。
    • 媒体管理:初始化MediaManager协调传感器与显示器资源。
  2. 主循环处理

    • 图像采集:通过sensor.snapshot()获取实时图像。
    • 目标识别:调用find_target_blob()在当前ROI内搜索"黑框白心"目标,结合多阈值和形态筛选规则验证目标。
    • 动态ROI调整:若锁定目标,缩小ROI至目标周围(提高效率);若目标丢失,逐步扩大ROI至全视野(重新搜索)。
    • 数据处理:计算目标与画面中心的偏差,通过smooth_target()平滑坐标,减少抖动。
    • 状态管理:通过is_locked标记目标状态,lost_frames计数连续丢失帧数,超过阈值则重置状态。
    • 数据发送与显示:通过UART发送目标状态及坐标,在图像上绘制辅助线、ROI和调试信息,最终通过显示器展示。
  3. 资源释放

    • 异常处理:捕获键盘中断或其他异常时,停止传感器、关闭显示器、释放媒体资源,确保系统安全退出。

技术名词解释

  1. HSV阈值(thr_white/thr_black)
    用于颜色(灰度)识别的范围参数。代码中通过灰度值范围定义"白色"和"黑色"区域,多阈值配置(列表形式)可适应不同光照下的颜色偏差(如强光/弱光下白色的灰度值范围变化)。

  2. ROI(Region of Interest,感兴趣区域)
    图像中需要重点处理的区域。通过限制处理范围减少计算量:目标锁定时缩小ROI(围绕目标),目标丢失时扩大ROI(逐步恢复全视野)。

  3. Blob分析
    对图像中连通的像素区域(色块)进行分析的技术。代码中通过find_blobs()识别黑色边框和白色中心的色块,结合面积、长宽比等特征筛选有效目标。

  4. 实心度(Solidity)
    色块实际像素数与外接矩形面积的比值,用于判断色块的"填充程度"。代码中利用实心度筛选空心黑色边框(实心度低),排除实心噪声区域。

  5. UART(通用异步收发传输器)
    一种串行通信协议,代码中用于将目标状态、坐标等数据发送到外部设备(如控制器),波特率115200确保数据传输稳定。

  6. 帧率(FPS)
    每秒处理的图像帧数,反映系统实时性。代码中通过time.ticks_ms()计算帧率,用于评估系统性能。

技术细节

1. 多阈值适配与目标识别逻辑

代码通过多阈值解决光照适应性问题,核心在于"黑框优先+白心验证"的双层识别策略:

# 多阈值配置(适应不同光照下的黑白识别)
thr_white = [(200, 255)]  # 白色中心的灰度范围(可扩展多组)
thr_black = [(0, 60)]     # 黑色边框的灰度范围(可扩展多组)def find_target_blob(img, roi):# 1. 先找黑色边框(多阈值遍历+合并相邻色块)black_blobs = []for t in thr_black:blobs = img.find_blobs([t], roi=roi, merge=True)  # merge=True合并相邻色块if blobs:black_blobs.extend(blobs)# 2. 对每个黑色边框验证是否包含白色中心for b_blob in black_blobs:# 筛选黑色边框(面积、长宽比、实心度)if not (MIN_RECT_AREA < b_blob.area() < MAX_RECT_AREA and0.5 < b_blob.w()/b_blob.h() < 2.0 and0.1 < b_blob.solidity() < 0.35):continue# 在黑色边框内部10%边距内搜索白色中心inner_roi = b_blob.rect()inner_margin = int(min(inner_roi[2], inner_roi[3]) * 0.1)inner_roi = (inner_roi[0] + inner_margin,inner_roi[1] + inner_margin,inner_roi[2] - 2*inner_margin,inner_roi[3] - 2*inner_margin)# 验证白色中心white_blobs = []for t in thr_white:w_blobs = img.find_blobs([t], roi=inner_roi)if w_blobs:white_blobs.extend(w_blobs)if white_blobs:w_blob = max(white_blobs, key=lambda b: b.area())  # 取最大白色块# 检查白心是否在黑框中心区域dx = abs(w_blob.cx() - b_blob.cx())dy = abs(w_blob.cy() - b_blob.cy())if dx < b_blob.w()*0.15 and dy < b_blob.h()*0.15:return (b_blob, w_blob)  # 返回匹配的黑框白心return (None, None)

代码解析

  • 多阈值遍历:通过thr_blackthr_white列表支持多组灰度范围,解决单一阈值在强光/弱光下失效的问题。
  • 合并相邻色块:merge=True确保断裂的黑色边框被识别为完整区域(如边框有缺口时仍能正常识别)。
  • 内边距ROI:在黑色边框内部10%区域搜索白色中心,避免背景干扰,确保"心在框内"的特征匹配。

2. 动态ROI与状态管理机制

通过ROI自适应调整平衡搜索效率与范围,结合状态标记实现稳定跟踪:

# 初始化全视野ROI
current_roi = (0, 0, sensor.width(), sensor.height())
is_locked = False
lost_frames = 0
MAX_LOST_FRAMES = 8  # 连续丢失8帧则重置状态while True:img = sensor.snapshot()b_blob, w_blob = find_target_blob(img, current_roi)if b_blob and w_blob:# 目标锁定:缩小ROI至目标周围is_locked = Truelost_frames = 0# 计算锁定状态下的ROI(目标周围90%范围)lock_roi = (max(0, b_blob.x() - int(b_blob.w()*0.05)),max(0, b_blob.y() - int(b_blob.h()*0.05)),min(sensor.width(), b_blob.w()*1.1),min(sensor.height(), b_blob.h()*1.1))current_roi = lock_roielse:# 目标丢失:逐步扩大ROIlost_frames += 1if lost_frames > MAX_LOST_FRAMES:is_locked = False# 每次扩大100像素(限制在全视野内)new_x = max(0, current_roi[0] - 50)new_y = max(0, current_roi[1] - 50)new_w = min(sensor.width(), current_roi[2] + 100)new_h = min(sensor.height(), current_roi[3] + 100)current_roi = (new_x, new_y, new_w, new_h)

代码解析

  • 锁定状态优化:目标锁定时ROI缩小为目标尺寸的1.1倍,减少背景处理量(如400x240图像中,ROI缩小后计算量可降低60%以上)。
  • 丢失恢复策略:目标丢失后,ROI每次向外扩展50像素(横向/纵向),逐步恢复全视野,避免瞬间扩大导致的计算量激增。
  • 状态容错机制:MAX_LOST_FRAMES=8允许短时间遮挡(约0.2~0.3秒,按30FPS计算),防止误判丢失。

3. 数据平滑与偏差计算

通过指数平滑减少抖动,结合视角补偿提升跟踪稳定性:

# 数据平滑与偏差计算
prev_x, prev_y = 0

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

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

相关文章

c语言中的数组可以用int a[3]来创建。写一次int就可以了,而java中要声明两次int类型像这样:int[] arr = new int[3];

C 语言数组只需写一次int&#xff0c;而 Java 需两次int相关声明&#xff0c;核心原因是两种语言的数组本质定义、类型系统设计和内存管理逻辑完全不同&#xff0c;具体可拆解为两点核心差异&#xff1a;一、C 语言&#xff1a;数组是 “内存块的类型绑定”&#xff0c;一次声明…

深度学习——详细教学:神经元、神经网络、感知机、激活函数、损失函数、优化算法(梯度下降)

神经网络实战&#xff1a; 深度学习——神经网络简单实践&#xff08;在乳腺癌数据集上的小型二分类示例&#xff09;-CSDN博客https://blog.csdn.net/2302_78022640/article/details/150779819?spm1001.2014.3001.5502 深度学习——神经网络&#xff08;PyTorch 实现 MNIST…

Ubuntu 软件安装的五种方法

1、App Store 安装 Ubuntu 里面有 一个App叫 “Ubuntu软件” 2、Sudo apt-get install 安装法 注意 使用apt工具安装软件&#xff0c;需要sudo&#xff0c;也就是root权限 例子 apt -get install git 会提示查看是否以root用户运行&#xff0c;install-安装sudo a…

Day15 (前端:JavaScript基础阶段)

接续上文&#xff1a;Day14——JavaScript 核心知识全解析&#xff1a;变量、类型与操作符深度探秘-CSDN博客 点关注不迷路哟。你的点赞、收藏&#xff0c;一键三连&#xff0c;是我持续更新的动力哟&#xff01;&#xff01;&#xff01; 主页:一位搞嵌入式的 genius-CSDN博…

在线旅游及旅行管理系统项目SQL注入

1.前言 之前在网上随便逛逛的时候&#xff0c;发现一个有各种各样的PHP项目的管理系统&#xff0c;随便点进一个查看&#xff0c;发现还把mysql版本都写出来了&#xff0c;而且还是PHP语言。 https://itsourcecode.com/free-projects/php-project/online-tours-and-travels-m…

Java网络编程(UDP, TCP, HTTP)

1. OSI 七层网络模型层级名称核心功能协议示例数据单元7应用层提供用户接口和网络服务HTTP, FTP, SMTP, DNS报文6表示层数据格式转换、加密/解密、压缩/解压SSL, JPEG, MPEG数据流5会话层建立、管理和终止会话连接NetBIOS, RPC会话数据4传输层端到端可靠传输、流量控制、差错校…

【P2P】P2P主要技术及RELAY服务1:python实现

P2P 技术 P2P(点对点)网络的核心是去中心化的网络拓扑和通信协议。DP的应用相对较少,但可能出现在: 路由优化:在一些复杂的P2P网络中,一个节点需要向另一个节点发送消息。为了找到一条延迟最低或跳数最少的路径,可能会用到类似最短路径的算法,而这类算法(如Bellman-F…

docker 安装 redis 并设置 volumes 并修改 修改密码(一)

在 Docker 中安装 Redis 并设置volumes持久化数据,同时修改 Redis 密码的完整步骤如下: 安装 Docker 如果还没有安装 Docker,可以参考以下步骤安装: 在 Alibaba Cloud Linux 上安装 Docker # 更新系统 sudo yum update -y# 安装 Docker 依赖 sudo yum install -y yum-util…

如何找出所有连接到本机指定端口的客户端 IP

在日常运维或排查网络问题时&#xff0c;我们常常需要知道&#xff1a;有哪些客户端正在连接我的服务&#xff1f;连接数是否异常&#xff1f;是否存在恶意扫描或 DDoS 行为&#xff1f;本文将教你使用一条简洁高效的 Linux 命令组合&#xff0c;统计连接到本机某个端口&#x…

java IDE安装idea社区版步骤

IntelliJ IDEA 社区版&#xff08;Community Edition&#xff09;是一款功能强大且完全免费的集成开发环境&#xff0c;非常适合 Java 和 Kotlin 初学者或进行基础开发2。我会为你提供详细的安装步骤。 &#x1f6e0; IntelliJ IDEA 社区版安装指南 &#x1f4cb; 系统要求与…

Agent智能体

什么是 Agent&#xff1f; Agent 是一个智能体&#xff0c;可以接收用户请求&#xff0c;利用大模型&#xff08;LLM&#xff09;的推理能力&#xff0c;自动决定&#xff1a; 自己回答还是调用外部工具&#xff08;数据库、API、脚本等&#xff09; 最终把结果返回给用户。 能…

【VSCode】使用VSCode打开md文件以及转化为PDF

【VSCode】使用VSCode打开md文件以及转化为PDF在 Visual Studio Code (VS Code) 中渲染 Markdown 并保存为 PDF&#xff0c;可以通过以下步骤实现。 首先安装好 VSCode&#xff0c;可以参考下述链接 https://blog.csdn.net/weixin_43848614/article/details/148042035 安装m…

苹果ImageIO零日漏洞分析:攻击背景与iOS零点击漏洞历史对比

苹果公司已紧急发布全生态系统安全更新&#xff0c;修复编号为CVE-2025-43300的ImageIO框架高危零日漏洞&#xff08;zero-day&#xff09;&#xff0c;该漏洞已被用于复杂的定向攻击。这是苹果在2025年修复的第七个零日漏洞&#xff0c;凸显iOS和macOS设备面临的威胁持续升级。…

面试 TOP101 递归/回溯专题题解汇总Java版(BM55 —— BM61)

8月刷题挑战&#xff0c;多重好礼等你拿 递归/回溯 题号题目名称核心思路时间复杂度空间复杂度代码亮点牛客原题链接BM55没有重复项数字的全排列使用回溯法生成所有排列O(n!)O(n)使用回溯法生成所有排列&#xff0c;逻辑清晰&#x1f517; 直达BM56有重复项数字的全排列使用回…

音频相关数学知识

时域&#xff08;Time domain&#xff09;是描述数学函数或物理信号对时间的关系&#xff0c;如果声音对应频率正负波动&#xff0c;对应事件x轴为时间&#xff0c;y轴为振幅频域信号在频率方面特性&#xff0c;如射频范围正弦型函数可以用来虚拟音频&#xff0c;正弦&#xff…

SAP-ABAP:SAP HANA 架构解析:主从(Scale-Out)与主备(High Availability)架构深度对比

SAP HANA 架构解析&#xff1a;主从&#xff08;Scale-Out&#xff09;与主备&#xff08;High Availability&#xff09;架构深度对比 一、架构概述 在SAP HANA数据库系统中&#xff0c;两种核心架构模式解决了不同的业务需求&#xff1a;主从架构&#xff08;Scale-Out&#…

【Hadoop】HDFS 分布式存储系统

Namenode是整个HDFS文件系统的前端&#xff0c;只有一个&#xff0c;管理数据块映射信息&#xff0c;配置副本策略&#xff0c;处理客户端的读写请求。Secondary namenode是namenode的热备&#xff0c;当active namenode出现故障时&#xff0c;快速切换为新的active namenode。…

[特殊字符] 如何在自己的仓库开发,同时保持同步原作者更新(超详细教程)

在开源协作开发中&#xff0c;很多时候我们会遇到这样一种情况&#xff1a; &#x1f449; 我们想基于一个开源项目继续开发&#xff0c;代码要推送到自己的仓库里&#xff1b; &#x1f449; 但原作者可能还会更新&#xff0c;我们也希望能随时把最新的改动同步过来。 本文以 …

Spring Ai (Function Calling / Tool Calling) 工具调用

1.工具调用介绍 工具调用是现代大语言模型&#xff08;LLM&#xff09;的一项重要能力&#xff0c;允许模型在生成回复时“决定”是否需要调用某个外部函数来获取信息或执行操作。例如&#xff1a; 联网搜索 &#xff08;实现查询到大模型未学习和RAG知识库中不存在的数据&am…

LabVIEW 正弦波噪声滤波

利用 LabVIEW 搭建程序&#xff0c;先合成含噪正弦波&#xff08;正弦信号与高通滤波后的噪声叠加&#xff09;&#xff0c;再通过低通滤波提取纯净正弦波&#xff0c;实现噪声去除&#xff0c;常用于信号处理、测试测量场景&#xff0c;验证滤波算法对正弦信号的降噪效果。​功…