当前位置: 首页 > news >正文

25电赛e题杂乱环境稳定识别矩形框(附源码)

识别并跟踪矩形目标

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

实现思路

  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.lryc.cn/news/606823.html

相关文章:

  • Vue3 Vue3中的响应式原理
  • StarRocks vs. Trino
  • 九联UNT403HS_海思MV320处理器_安卓9-优盘强刷刷机包
  • 嵌入式 Linux 深度解析:架构、原理与工程实践(增强版)
  • 企业级LLM智能引擎 的完整解决方案,整合了 SpringAI框架、RAG技术、模型控制平台(MCP)和实时搜索,提供从架构设计到代码实现的全面指南:
  • cloudflare worker + Cloudflare AI Gateway
  • 如何在不依赖 Office 的情况下转换 PDF 为可编辑文档
  • python中appium
  • K8S周期性备份etcd数据实战案例
  • 精通分类:解析Scikit-learn中的KNN、朴素贝叶斯与决策树(含随机森林)
  • 应用药品注册证识别技术,为医药行业的合规、高效与创新发展提供核心驱动力
  • 智能图书馆管理系统开发实战系列(四):后端C++ DLL开发与模块化设计
  • Dify版本升级实操
  • 体育直播系统搭建:核心数据详细接入指南
  • 网络编程-加密算法
  • CCleaner是否被过誉了?C盘满了怎么办?用ccleaner清除C盘垃圾,3款电脑系统磁盘清理和优化软件
  • 应用Builder模式在C++中进行复杂对象构建
  • Vue与Ajax快速入门
  • GXP6040K压力传感器可应用于医疗/汽车/家电
  • Python Flask框架Web应用开发完全教程
  • 【stm32】GPIO
  • 第3章 AB实验的统计学知识
  • 从Web2.0到Web3.0:社交参与方式的重塑与延伸
  • 报错[Vue warn]: Failed to resolve directive: else如何解决?
  • Linux9 root密码修改
  • 数据结构第5问:什么是队列?
  • 【科普】怎么理解Modbus、TCP、UDP
  • C++入门自学Day4-- c++类与对象(友元)
  • 《软件测试与质量控制》实验报告一 测试用例设计
  • 新一代PLC控制软件平台EsDA-AWStudio