识别并跟踪矩形目标

识别视频中符合矩形轮廓的目标区域,并标记中心点位置。

实现思路

  1. **图像预处理:灰度 + 二值化
  2. **闭运算消除孔洞
  3. 二值化处理
  4. 查找并筛选矩形轮廓
  5. 解算中心点
  6. 目标筛选
  7. 结果绘制

环境

使用 OpenCV 和 python:

图像预处理:灰度 + 二值化

将读取到的帧转换为灰度图,再进行阈值二值化处理。
这里采用 反向二值化(白底黑物体),便于检测黑色矩形:

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(gray, 120, 255, cv2.THRESH_BINARY_INV)

在这里插入图片描述

闭运算消除孔洞

closed = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_RECT, (50, 50)))
  • 闭运算 : 膨胀后腐蚀,可去除图中小孔洞和断裂,提高矩形轮廓连通性。
    在这里插入图片描述
    闭运算后图像(轮廓更完整)

查找并筛选矩形轮廓

使用 cv2.findContours() 提取所有闭合轮廓,再筛选出“近似矩形”的轮廓:

is_rect, approx = is_approx_rect(cnt)
def is_approx_rect(contour, epsilon_factor=0.02):     peri = cv2.arcLength(contour, True)     approx = cv2.approxPolyDP(contour, epsilon_factor * peri, True)     return (4 <= len(approx) <= 5 and cv2.isContourConvex(approx)), approx
  • 调用 cv2.approxPolyDP() 将轮廓多边形逼近
  • 条件:点数为 4~5 且轮廓是凸的

在这里插入图片描述

                 保留下的近似矩形轮廓图像

解算中心点

通过轮廓的几何矩获取中心点坐标:

def calc_center(approx):     M = cv2.moments(approx)     if M["m00"] == 0:         return None     return int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"])

目标筛选(追踪最近矩形)

  • 第一帧:选取面积最大的矩形
  • 后续帧:优先选取与上一帧中心点距离最近的矩形
  • 距离在 50 像素内的多个候选中,选择面积最大的
    距离计算函数如下:
cv2.drawContours(display_frame, [approx], -1, (0, 0, 255), 5)
cv2.circle(display_frame, center, 7, (0, 0, 255), -1)

结果绘制

cv2.drawContours(display_frame, [approx], -1, (0, 0, 255), 5) cv2.circle(display_frame, center, 7, (0, 0, 255), -1)
  • 红色画出识别轮廓
  • 红点标记中心点位置
    在这里插入图片描述
    最终效果
    电赛e题,杂乱环境稳定识别,-哔哩哔哩

完整cv代码

创作不易,点个赞再走哦

import cv2
import numpy as npdef is_approx_rect(contour, epsilon_factor=0.02):peri = cv2.arcLength(contour, True)approx = cv2.approxPolyDP(contour, epsilon_factor * peri, True)return (4 <= len(approx) <= 5 and cv2.isContourConvex(approx)), approxdef calc_center(approx):M = cv2.moments(approx)if M["m00"] == 0:return Nonereturn int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"])def distance(p1, p2):return np.sqrt((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2)def main():cap = cv2.VideoCapture("222.mp4")if not cap.isOpened():print("打开视频失败")returnprev_center = Nonewhile True:ret, frame = cap.read()if not ret:breakgray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)_, binary = cv2.threshold(gray, 120, 255, cv2.THRESH_BINARY_INV)closed = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_RECT, (50, 50)))contours_data = cv2.findContours(closed, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)contours = contours_data[1] if len(contours_data) == 3 else contours_data[0]candidates = []for cnt in contours:is_rect, approx = is_approx_rect(cnt)if is_rect:center = calc_center(approx)if center:candidates.append((approx, center, cv2.contourArea(approx)))if not candidates:selected = Noneelif prev_center is None:selected = max(candidates, key=lambda x: x[2])else:candidates.sort(key=lambda x: distance(x[1], prev_center))top_n = [candidates[0]]for c in candidates[1:]:if distance(c[1], prev_center) - distance(candidates[0][1], prev_center) < 50:top_n.append(c)else:breakselected = max(top_n, key=lambda x: x[2])display_frame = frame.copy()contour_img = np.zeros_like(frame)if selected:approx, center, _ = selectedcv2.drawContours(display_frame, [approx], -1, (0, 0, 255), 5)cv2.circle(display_frame, center, 7, (0, 0, 255), -1)cv2.drawContours(contour_img, [approx], -1, (0, 255, 0), 3)prev_center = centerelse:prev_center = Nonecv2.imshow("原视频", display_frame)cv2.imshow("二值化", binary)cv2.imshow("闭运算", closed)cv2.imshow("轮廓", contour_img)if cv2.waitKey(1) & 0xFF == ord('q'):breakcap.release()cv2.destroyAllWindows()if __name__ == "__main__":main()

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

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

相关文章

【前端安全】聊聊 HTML 闭合优先级和浏览器解析顺序

【前端安全】聊聊浏览器解析顺序和 HTML 闭合优先级 最近在研究 XSS 的时候&#xff0c;发现一个特别容易被忽略的问题 —— 浏览器到底是怎么解析 HTML 的&#xff1f;为什么有些 payload 成功了&#xff0c;有些却怎么试都不行&#xff1f;其实这跟标签的闭合优先级还有解析顺…

PHP-分支语句、while循环、for循环

分支语句 无论在何种编程语言中&#xff0c;流程控制都是很重要的内容。由于 PHP 的大部分语法都继承了C语言的特点&#xff0c; 因此在流程控制方面&#xff0c;PHP 有着和C语言类似的流程控制。 if else 语句是流程控制中根据条件判断执行的一种。该语句执行时先对条件进行判…

并发编程常用工具类(下):CyclicBarrier 与 Phaser 的协同应用

在并发编程中&#xff0c;除了CountDownLatch和Semaphore&#xff0c;CyclicBarrier和Phaser也是实现多线程协作的重要工具。它们在处理多阶段任务同步、动态调整参与线程等场景中展现出独特价值。本文作为并发工具类系列的第二篇&#xff0c;将深入解析CyclicBarrier和Phaser的…

机器人焊接节气装置

在摩托车制造过程中&#xff0c;精密部件的焊接质量直接影响整车的安全性和操控性能。以发动机缸体焊接为例&#xff0c;传统手工焊接容易出现焊缝不均匀的问题&#xff0c;而采用六轴弧焊机器人后&#xff0c;焊接精度能控制在0.1毫米以内。日本川崎重工的生产数据显示&#x…

使用yolo11训练食物浪费检测数据集VOC+YOLO格式6734张32类别步骤和流程

【数据集介绍】数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件)图片数量(jpg文件个数)&#xff1a;6734标注数量(xml文件个数)&#xff1a;6734标注数量(txt文件个数)&#xff1…

掌握PowerPC架构与编程技巧:技术资料详解

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;PowerPC是一种高性能的RISC架构&#xff0c;最初由IBM、Motorola和Apple联合开发&#xff0c;被设计用于高端工作站和服务器&#xff0c;同时广泛应用于嵌入式系统、航空电子设备、游戏主机和超级计算机等领域。…

VR 企业展厅:开启数字化展示新时代

在当今数字化浪潮席卷各行各业的时代&#xff0c;企业的展示与宣传方式也在不断革新。VR&#xff08;虚拟现实&#xff09;技术的出现&#xff0c;为企业展厅带来了全新的变革&#xff0c;使其从传统的实体展示空间&#xff0c;转变为具有无限可能的数字化虚拟空间。一、VR 企业…

测试用例颗粒度全解析

引言&#xff1a;为什么颗粒度是测试团队的“隐形门槛”&#xff1f;在软件测试领域&#xff0c;测试用例颗粒度&#xff08;即测试用例的详细程度&#xff09;看似是一个基础问题&#xff0c;却常常成为团队协作的“隐形门槛”。某电商平台测试团队曾出现过这样的窘境&#xf…

分布式锁的基本原理和基于lua脚本的实现(Redisson)

为了确保分布式锁可用&#xff0c;我们要确保锁的实现同时满足以下四个条件&#xff1a;- 互斥性。在任意时刻&#xff0c;只有一个客户端能持有锁。- 不会发生死锁。即使有一个客户端在持有锁的期间崩溃而没有主动解锁&#xff0c;也能保证后续其他客户端能加锁。- 解铃还须系…

智慧园区数字孪生全生命周期交付体系:从虚拟建模到全域智联的快速交付新常态

在数字经济与绿色低碳转型的双重驱动下&#xff0c;智慧园区建设正经历从“物理空间堆砌”到“数据智能驱动”的范式革命。数字孪生技术作为核心引擎&#xff0c;通过构建物理园区的虚拟镜像&#xff0c;实现虚实空间的毫秒级同步与智能协同&#xff0c;推动园区管理向全要素感…

电脑忘记开机密码怎么办?【图文详解】5种方法重置/更改/取消/设置开机密码?

一、问题背景谁都有马虎的时候&#xff0c;要是突然忘了电脑开机密码&#xff0c;就只能对着登录界面干着急&#xff0c;没法打开电脑处理工作、查看文件&#xff0c;太影响效率了。别慌&#xff0c;其实有不少简单实用的办法能解除或重置密码&#xff0c;下面就来一一介绍&…

Go语言select

select是什么select是Go语言层面提供的一种多路复用机制&#xff0c;用于检测当前goroutine连接的多个channel是否有数据准备完毕&#xff0c;可用于读或写。Go语言的select语句&#xff0c;是用来起一个goroutine监听多个Channel的读写事件&#xff0c;提高从多个Channel获取信…

VUE+SPRINGBOOT从0-1打造前后端-前后台系统-整体示例

一、注册、登录、密码找回二、VUE前台系统三、VUE后台系统

深入解析SmolVLA:VLM与动作专家间的注意力机制交互

在机器人学习领域&#xff0c;如何有效地将视觉语言模型&#xff08;VLM&#xff09;的强大感知能力与低级动作控制相结合&#xff0c;是实现通用机器人智能的关键挑战。SmolVLA&#xff08;Small Vision-Language-Action&#xff09;架构正是在这一背景下应运而生&#xff0c;…

Spring Security 认证与授权实现机制

Spring Security 是一个功能强大且高度可定制的身份验证和访问控制框架&#xff0c;其认证和授权实现机制如下&#xff1a;一、认证(Authentication)实现 1. 核心组件 AuthenticationManager&#xff1a;认证入口点&#xff0c;委托给AuthenticationProviderAuthenticationProv…

开源的时间跟踪工具TimeTagger

简介 什么是 TimeTagger &#xff1f; TimeTagger 是一个开源的时间跟踪工具&#xff0c;旨在帮助用户记录和分析他们的时间使用情况。它提供了一个互动的用户界面和强大的报告功能&#xff0c;适合个人和自由职业者使用。 主要特点 直观的用户界面&#xff1a;基于互动时间线…

学习游戏制作记录(角色属性和状态脚本)8.4

1.实现简单的角色属性创建CharactorState脚本&#xff1a;挂载在敌人和玩家身上public float damage;//角色伤害public float maxHp;//最大生命[SerializeField] private float currentHealth;//当前生命void Start(){currentHealth maxHp;//初始化将当前生命设置为最大生命}p…

04-Chapter02-Example01

文章介绍 1、完善项目结构 1.1 新建第二章对应模块Chapter021.2 新建模块Chapter02对应包com.itheima1.3 在包com.itheima下新建class类 &#xff0c;类名称Example01.java项目结构如下&#xff1a;2、编写Example01.java代码 P38 package com.itheima;public class Example01…

【达梦MPP(带主备)集群搭建】

达梦MPP&#xff08;带主备&#xff09;集群搭建 为了提高MPP系统可靠性&#xff0c;克服由于单节点故障导致整个系统不能继续正常工作的问题&#xff0c;DM在普通的MPP系统基础上&#xff0c;引入数据守护主备机制&#xff0c;为每一个MPP节点配置一个实时备库作为备份节点&a…

Java基础学习(一):类名规范、返回值、注释、数据类型

目录 一、类名规范二、返回值三、注释四、数据类型 1. 基本类型2. 引用类型3. 强制数据类型转换4. 进制5. 进制的转换6. 超范围运算 相关文章 Java基础学习&#xff08;二&#xff09;&#xff1a;Java中的变量和常量、final&#xff08;重点&#xff09;、运算、字符串 了…