yolov8 区域多类别计数

news2024/12/22 4:26:02

yolov8 区域多类别计数

  • 1. 基础
  • 2. 计数功能
    • 2.1 计数模块
    • 2.2 判断模块
  • 3. 初始代码
  • 4. 实验结果
  • 5. 完整代码
  • 6. 源码

1. 基础

本项目是在 Windows+YOLOV8环境配置 的基础上实现的,测距原理可见上边文章

2. 计数功能

2.1 计数模块

在指定区域内计数模块
region_points为指定区域,可设置为任意形状

region_points = [(20, 20), (20, 600), (1200, 600), (1200, 20)]
count_class1 = 0
count_class2 = 0
for i, box in enumerate(boxes):
   x1, y1, x2, y2 = box[:4]
   x_center = (x1 + x2) / 2
   y_center = (y1 + y2) / 2
   center_point = (int(x_center), int(y_center))
   if is_inside_region(center_point, region_points):
       if box[-1] == 0:  # 类别1的标签.人
           count_class1 += 1
       elif  box[-1] == 2:  # 类别2的标签,车
           count_class2 += 1

2.2 判断模块

def is_inside_region(point, region_points):
    """
    判断点是否在指定区域内
    """
    return cv2.pointPolygonTest(np.array(region_points), point, False) >= 0

3. 初始代码


import cv2
import numpy as np
from ultralytics import YOLO


def is_inside_region(point, region_points):
    """
    判断点是否在指定区域内
    """
    return cv2.pointPolygonTest(np.array(region_points), point, False) >= 0

def detect():

    model = YOLO("yolov8n.pt")
    cv2.namedWindow('region couter', cv2.WINDOW_NORMAL)
    cv2.resizeWindow('region couter', 1280, 360)  # 设置宽高
    cap = cv2.VideoCapture('ultralytics/assets/a3.mp4')
    out_video = cv2.VideoWriter('output.avi', cv2.VideoWriter_fourcc(*'XVID'), 30, (2560, 720))

    region_points = [(20, 20), (20, 600), (1200, 600), (1200, 20)]
    region_points_np = np.array(region_points)

    assert cap.isOpened(), "Error reading video file"
    while cap.isOpened():
        success, im0 = cap.read()
        if not success:
            print("Video frame is empty or video processing has been successfully completed.")
            break
        tracks = model.track(im0, persist=True)
        annotated_frame = tracks[0].plot()
        boxes = tracks[0].boxes.data
        count_class1 = 0
        count_class2 = 0
        for i, box in enumerate(boxes):
            x1, y1, x2, y2 = box[:4]
            x_center = (x1 + x2) / 2
            y_center = (y1 + y2) / 2
            center_point = (int(x_center), int(y_center))
            if is_inside_region(center_point, region_points):
                if box[-1] == 0:  # 类别1的标签.人
                    count_class1 += 1
                elif  box[-1] == 2:  # 类别2的标签,车
                    count_class2 += 1
        cv2.polylines(annotated_frame, [region_points_np], isClosed=True, color=(255, 0, 0), thickness=2)
        print("Number of objects in class 1:", count_class1)
        print("Number of objects in class 2:", count_class2)

        cv2.imshow("region couter", annotated_frame)
        out_video.write(annotated_frame)
        if cv2.waitKey(1) == ord('q'):
            break
    out_video.release()
    cap.release()
    cv2.destroyAllWindows()
if __name__ == '__main__':
    detect()

4. 实验结果

本实验可以计数多种类别
(1)区域计数实验
在这里插入图片描述
(2)如需把区域背景换成填充色,可将上边代码里的

cv2.polylines(annotated_frame, [region_points_np], isClosed=True, color=(255, 0, 0), thickness=2)

替换为

region_mask = np.zeros_like(annotated_frame)
cv2.fillPoly(region_mask, [region_points_np], color=(255, 0, 0))
# 使用透明度将填充后的区域与原始帧混合
alpha = 0.2  # 调整透明度
annotated_frame = cv2.addWeighted(annotated_frame, 1 - alpha, region_mask, alpha, 0)

请添加图片描述
(3)计数在图上显示
annotated_frame = cv2.addWeighted(annotated_frame, 1 - alpha, region_mask, alpha, 0)添加

text1 = "count_class1:%d" % count_class1
text2 = "count_class2:%d" % count_class2
cv2.putText(annotated_frame, text1, (20, 30), cv2.FONT_ITALIC, 1.0, (0, 255, 255), 2)
cv2.putText(annotated_frame, text2, (20, 60), cv2.FONT_ITALIC, 1.0, (0, 255, 255), 2)

在这里插入图片描述

5. 完整代码

import cv2
import numpy as np
from ultralytics import YOLO


def is_inside_region(point, region_points):
    """
    判断点是否在指定区域内
    """
    return cv2.pointPolygonTest(np.array(region_points), point, False) >= 0

def detect():

    model = YOLO("yolov8n.pt")
    cv2.namedWindow('region couter', cv2.WINDOW_NORMAL)
    cv2.resizeWindow('region couter', 1280, 360)  # 设置宽高
    cap = cv2.VideoCapture('ultralytics/assets/a3.mp4')
    out_video = cv2.VideoWriter('output.avi', cv2.VideoWriter_fourcc(*'XVID'), 30, (2560, 720))

    region_points = [(20, 20), (20, 600), (1200, 600), (1200, 20)]
    region_points_np = np.array(region_points)

    assert cap.isOpened(), "Error reading video file"
    while cap.isOpened():
        success, im0 = cap.read()
        if not success:
            print("Video frame is empty or video processing has been successfully completed.")
            break
        tracks = model.track(im0, persist=True)
        annotated_frame = tracks[0].plot()
        boxes = tracks[0].boxes.data
        count_class1 = 0
        count_class2 = 0
        for i, box in enumerate(boxes):
            x1, y1, x2, y2 = box[:4]
            x_center = (x1 + x2) / 2
            y_center = (y1 + y2) / 2
            center_point = (int(x_center), int(y_center))
            if is_inside_region(center_point, region_points):
                if box[-1] == 0:  # 类别1的标签.人
                    count_class1 += 1
                elif  box[-1] == 2:  # 类别2的标签,车
                    count_class2 += 1
        # cv2.polylines(annotated_frame, [region_points_np], isClosed=True, color=(255, 0, 0), thickness=2)
        region_mask = np.zeros_like(annotated_frame)
        cv2.fillPoly(region_mask, [region_points_np], color=(255, 0, 0))
        # 使用透明度将填充后的区域与原始帧混合
        alpha = 0.2  # 调整透明度
        annotated_frame = cv2.addWeighted(annotated_frame, 1 - alpha, region_mask, alpha, 0)

        text1 = "count_class1:%d" % count_class1
        text2 = "count_class2:%d" % count_class2
        cv2.putText(annotated_frame, text1, (20, 30), cv2.FONT_ITALIC, 1.0, (0, 255, 255), 2)
        cv2.putText(annotated_frame, text2, (20, 60), cv2.FONT_ITALIC, 1.0, (0, 255, 255), 2)
        print("Number of objects in class 1:", count_class1)
        print("Number of objects in class 2:", count_class2)

        cv2.imshow("region couter", annotated_frame)
        out_video.write(annotated_frame)
        if cv2.waitKey(1) == ord('q'):
            break
    out_video.release()
    cap.release()
    cv2.destroyAllWindows()
if __name__ == '__main__':
    detect()

6. 源码

可以去 Windows+YOLOV8环境配置 下载源码,然后把上边主代码贴进去运行即可

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法课程笔记——STL键值对map

map当下标无限的数组 重点是对应关系&#xff0c;一般不修改compare 类比set 没有lowerbound&#xff0c;因为遍历是无序的 ; map不能用sort函数排序 但可用vector转化为map使用 std::set<std::pair<TKEY, mutable TVAL> > ≈ std::map<TKEY, TVAL>

Java基础入门1-2

跟着韩顺平老师的30天入门java课程学习&#xff0c;整理一下自己的笔记&#xff0c;方便回顾知识点和复习。 另附上视频链接&#xff1a;0034_韩顺平Java_变量原理_哔哩哔哩_bilibili 第一章&#xff1a;学习前的了解 第二章&#xff1a;Java概述 2.1什么是程序&#xff1f…

C++ STL标准库,rotate函数详解

rotate翻译 rotate v.&#xff08;使&#xff09;旋转&#xff0c;&#xff08;使&#xff09;转动&#xff1b;&#xff08;人员&#xff09;轮换&#xff0c;轮值&#xff1b;轮种&#xff0c;轮作&#xff1b;定期调换地点&#xff08;或位置&#xff09;adj.&#xff08;…

【WSL】单机大模型前的基础环境配置

前言&#xff1a;在上一篇文章中&#xff0c;我们完成了WSL的部署&#xff0c;但是在大模型搭建&#xff08;尤其是Langchain&#xff09;前&#xff0c;还碰到了不少的坑&#xff0c;查找了不少的文章&#xff0c;所以本篇文章就做一个记录&#xff0c;避免以后再走冤枉路。 …

python学习笔记(集合)

知识点思维导图 # 直接使用{}进行创建 s{10,20,30,40} print(s)# 使用内置函数set()创建 sset() print(s)# 创建一个空的{}默认是字典类型 s{} print(s,type(s))sset(helloworld) print(s) sset([10,20,30]) print(s) s1set(range(1,10)) print(s1)print(max:,max(s1)) print(m…

入门指南:网站UI原型设计的简单方法

从零开始做网站UI原型设计&#xff0c;真的很有成就感&#xff01;那么&#xff0c;UI设计师从零开始做网站UI原型设计需要经历哪些过程呢&#xff1f;设计网站UI原型的第一步&#xff1a;绘制网站线框。本文将主要分为两个阶段&#xff1a;网站线框和原型绘制。 如何制作网站…

HDFS详解(Hadoop)

Hadoop 分布式文件系统&#xff08;Hadoop Distributed File System&#xff0c;HDFS&#xff09;是 Apache Hadoop 生态系统的核心组件之一&#xff0c;它是设计用于存储大规模数据集并运行在廉价硬件上的分布式文件系统。 1. 分布式存储&#xff1a; HDFS 将文件分割成若干块…

SAP Fiori开发中的JavaScript基础知识15 - 原型,object,constructor,class,继承

1. 前言 本文将介绍JavaScript中的核心概念 - 原型&#xff0c;并会介绍基于原型的应用场景object&#xff0c;constructor&#xff0c;class&#xff0c;继承。 本文会将这几个核心概念汇总在一篇博客中&#xff0c;因为这些概念是触类旁通的&#xff0c;希望对你有帮助。 …

【linux】编译器使用

目录 1. gcc &#xff0c;g 编译器使用 a. 有关gcc的指令&#xff08;g同理&#xff09; 2. .o 文件和库的链接方式 a. 链接方式 b. 动态库 和 静态库 优缺点对比 c. debug 版本 和 release 版本 1. gcc &#xff0c;g 编译器使用 a. 有关gcc的指令&#xff08;g同理&…

CCF区块链会议--Middleware 2024 截止5.24 附录用率

会议名称&#xff1a;Middleware CCF等级&#xff1a;CCF B类会议 类别&#xff1a;软件工程/系统软件/程序设计语言 录用率&#xff1a;2022年录用率38%&#xff08;8/21&#xff09; Topics of Interest The Middleware conference seeks original submissions of resear…

销冠必备:高效跟进客户的四个技巧

作为一名销售&#xff0c;高效而精准地跟进客户是取得成功的关键。今天&#xff0c;我将分享四个技巧&#xff0c;让你也能够高效的跟进客户。 1、善于发问 通过多询问客户&#xff0c;你可以更好地了解客户的需求和痛点。在与客户交流时&#xff0c;不要只是简单地回答问题&…

SpringCloud基础 Consul的引入

前言 首先是为什么引入consul这个组件 我们知道微服务分为很多个模块,这里模块中相互调用,我使用硬编码的模式是不好的 比如微服务模块需要更新的时候,我们使用硬编码的方式可能需要修改很多个地方 但是使用consul之后,就引入了注册中心,我们只需要将对应的服务注册为节点 这样…

如何修复U盘在Windows 10上断开又重新连接的问题?这里有方法

序言 有时,当你把U盘连接到电脑上时,U盘每隔几秒钟就会断开连接并重新连接,这导致你无法正常复制和传输文件,这真的很烦人。硬件或驱动程序可能有问题。 在这种情况下,你需要确保此U盘与其他计算机是否正常工作。如果是,则表示你的驱动器没有问题。如果不是,不要担心。…

我们该如何看待AIGC(人工智能)

目录 AIGC的概述&#xff1a; AIGC的发展经历&#xff1a; AIGC的概述&#xff1a; [TOC]( &#x1f680;文章目录) ---AIGC全称为AI-Generated Content&#xff0c;指基于生成对抗网络GAN、大型预训练模型等人工智能技术&#xff0c;通过已有数据寻找规律&#xff0c;并通过…

服务网关GateWay基础

1. 网关基础介绍1.1 网关是什么1.2 为啥要用网关1.3 常见的网关组件NginxNetflix ZuulSpring Cloud GatewayKongAPISIX综合比较 2. gateWay的使用2.1 springCloud整合gateway2.2 GateWay的相关用法2.3 GateWay路由使用示例基本用法转发/重定向负载请求动态路由 2.5 断言(Predic…

Rust腐蚀服务器定制地图开服

Rust腐蚀服务器定制地图开服 大家好我是艾西一个做服务器租用的网络架构师。Rust腐蚀这个游戏有很多的插件mod作者&#xff0c;在地图制作这一块也是一样&#xff0c;有些好玩的地图可能大家在map网站找到了但是不知道怎么操作设置那么今天艾西给大家说下特定定制地图怎么弄。…

L1-099 帮助色盲 - java

L1-099 帮助色盲 代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB 栈限制 8192 KB 题目描述&#xff1a; 在古老的红绿灯面前&#xff0c;红绿色盲患者无法分辨当前亮起的灯是红色还是绿色&#xff0c;有些聪明人通过路口的策略是这样的&#xff1a;当红灯或绿灯亮起时&am…

性能测试工具三——perf + FlameGraph(采样测试)

1. 安装 sudo apt install linux-tools-common 如果没安装成功可尝试制定特定内核版本的工具&#xff0c;例如sudo apt install linux-tools-6.5.0-27-generic。 2. 使用perf Step1&#xff1a;编译得到可执行程序&#xff0c;假设是a.out。 Step2&#xff1a;执行类似如下指…

docker中的资源控制

前言 docker 使用cgrqup控制资源&#xff0c;K8S 里面也有limit&#xff08;使用上限&#xff09; docker通过cgroup来控制容器使用的资源配额&#xff0c;包括CPU、内存、磁盘三大方面&#xff0c;基本覆盖了常见的资源配额和使用量控制。 Cgroup 是 Control …