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

opencv学习中——车辆检测代码

(1)自学一个月,白天上班,晚上看b站视频+大模型求教,写了个视频车辆检测代码,记录一下。

(2)Cars.mp4视频在上一篇文章中。

(3)最终效果不太好,每一帧识别的外框会变动甚至嵌套,不知道是不是前面的形态学处理和轮廓识别的问题。可以通过YOLOv8 + ByteTrack 集成代码解决,还没学,等之后对比下效果。

import cv2 import numpy as np video_path = 'D:/video/' cap = cv2.VideoCapture(f'{video_path}Cars.mp4') #检测线高度,frame.shape是(768, 1364, 3),取550在视频下部 line_high = 550 #线的偏移量 offset = 2 #存放有限车辆的数组 cars = [] #统计车的数量 carno = 0 def center(x, y, w, h): x1 = int(w/2) y1 = int(h/2) cx = x + x1 cy = y + y1 return cx, cy #背景减除,MOG2是改进版本,可以直接apply,需要先进行灰度及去噪处理 sub = cv2.createBackgroundSubtractorMOG2() #sub = cv2.bgsegm.BackgroundSubtractorMOG() #形态学kernel,视频内容是行人、车辆、动物等自然运动目标则首选椭圆核 kernel_ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) while True: ret, frame = cap.read() if not ret: break #(1)应用背景减除 #灰度 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #去噪(高斯) blur = cv2.GaussianBlur(gray, (3, 3), 5) fg_mask = sub.apply(blur) # 查看像素值的唯一值 unique_values = np.unique(fg_mask) #print("像素值种类:", unique_values) # 如果输出 [0, 127, 255],说明是三值图 # 如果输出 [0, 255],才是二值图 # 一般默认是输出三值图,开启阴影检测 + 后处理过滤 #(2)阴影过滤:将灰色阴影(127)归为背景(0),只保留纯前景(255) _, fg_clean = cv2.threshold(fg_mask, 127, 255, cv2.THRESH_BINARY) #(3)形态学去噪+填洞:使用椭圆核,先开运算(去除噪声)后闭运算(填充空洞) fg_mask_ellipse = cv2.morphologyEx(fg_clean, cv2.MORPH_OPEN, kernel_ellipse) fg_mask_ellipse = cv2.morphologyEx(fg_mask_ellipse, cv2.MORPH_CLOSE, kernel_ellipse) #(4)轮廓筛选,使用cv2.RETR_EXTERNAL,不用cv2.RETR_TREE # 只需要最外层轮廓,不然会引入无效信息,增加计算开销,增加筛选难度 contours, _ = cv2.findContours(fg_mask_ellipse, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 过滤掉面积小的残留噪声 min_area = 500 valid_contours = [cnt for cnt in contours if cv2.contourArea(cnt) > min_area] #(5)绘图展示 result = frame.copy() # 复制原始彩色帧 #绘制检测线 cv2.line(result, (400, line_high), (1200, line_high), (0, 255, 0), 2) for (i, c) in enumerate(valid_contours): x, y, w, h = cv2.boundingRect(c) #对车辆宽高进行判断,以验证是否是有效车辆 # 根据视频分辨率动态计算最小尺寸 frame_h, frame_w = frame.shape[:2] min_w = int(frame_w * 0.06) # 最小宽度为帧宽的xx% min_h = int(frame_h * 0.08) # 最小高度为帧高的xx% isValid = (w >= min_w) and (h >= min_h) if not isValid: continue #不满足则跳过接下来的步骤重新步入循环 #到这里都是有效车 cv2.rectangle(result, (x, y), (x+w, y+h), (0, 0, 255), 2) cpoint = center(x, y, w, h) cars.append(cpoint) for (x, y) in cars: #要有一条线 #有范围,上下2个像素 #从数组中减去 if(( y > line_high - offset) and (y < line_high + offset)): carno += 1 cars.remove((x, y)) print(carno) #对比之后确实椭圆核的每一帧都处理的更细腻 cv2.putText(result, 'Cars Count: ' + str(carno), (500, 60), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 5) cv2.imshow('Video', result) #cv2.imshow('Mask', fg_mask) #cv2.imshow('Clean', fg_clean) #cv2.imshow('Ellipse Kernel Result', fg_mask_ellipse) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()

翻译

搜索

复制

src="">
http://www.jsqmd.com/news/1238586/

相关文章:

  • 多智能体操作系统时代来临:从AgenticOS看AI Agent底层架构设计与实战
  • TI EMIFA电源管理与时序配置实战:从SDRAM到异步存储器的嵌入式系统优化
  • OMTO-MQ消息队列服务架构解析与实践指南
  • 头痛缓解方案 —— 鸿蒙AI智能助手开发全流程解析
  • SmartHomeAI---
  • 阿里云返佣折扣详解:如何通过典名科技获得最高优惠
  • 从RNN到Attention:序列建模的核心突破与实现
  • 硬盘坏道检测与修复全攻略
  • UE5.3插件打包全流程指南:从源码到二进制环境避坑实践
  • CodeGraph轻量化代码知识图谱核心技术解析与应用
  • AI编程助手token优化:MCP技术实现99%消耗降低
  • C++对象编程:从基础概念到高级实践
  • 深度学习模型量化技术:PTQ原理与实践指南
  • 奇迹MU剑与翼跨服养号与积分速刷指南
  • GoldHEN金手指管理器:1490+游戏修改的终极解决方案
  • ngx_writev
  • 你的 AI 不是下属,是组织:为什么多智能体要借管理学和社会学来建
  • HarmonyOS 6.1 AI融合实战:端侧智能与HiAI Foundation的极致性能
  • C++11 std::function与std::bind核心用法与实现原理
  • SpringBlade Sword:企业级微服务前端开发终极指南
  • HarmonyOS 6.1 生态整合实战:服务卡片与“万能卡片”的生态玩法
  • TI HDVPSS数据通路配置:从寄存器解析到画中画实战
  • 嵌入式EMIFA接口与NAND Flash时序配置实战:从理论计算到驱动调试
  • JSON与JSONPATH:数据查询与处理核心技术解析
  • Agent 大厂面试题・|字节跳动|淘汰85%候选人的AI综合面,Agent全链路连环追问附满分作答
  • 有故事但不会画画?这5款AI工具帮你一键生成漫画
  • LeetCode hot 100—1
  • 移动性水文监测物联网解决方案
  • Dockerfile核心指令详解与容器化最佳实践
  • 解密Palantir系列三:6.AIP · 别再把 AIP 当成一个聊天框:四个入口,四种工作