Python+OpenCV编写车辆计数器系统

 更新时间:2022年05月30日 09:21:33   作者:woshicver  
本文,我们将使用欧几里德距离跟踪和轮廓的概念在 Python 中使用 OpenCV 构建车辆计数器系统,文中的示例代码讲解详细,感兴趣的可以了解一下

介绍

本文,我们将使用欧几里德距离跟踪和轮廓的概念在 Python 中使用 OpenCV 构建车辆计数器系统。

对象追踪

对象跟踪是在视频中定位移动对象的过程。在 OpenCV 中有多种技术可以执行对象跟踪。可以针对 2 种情况执行对象跟踪:

  • 跟踪单个对象
  • 跟踪多个对象

在这里,我们将执行多对象跟踪方法,因为我们在一个时间范围内有多辆车。

流行的追踪算法

DEEP SORT:它是最广泛使用和非常有效的目标跟踪算法之一,它适用于 YOLO 目标检测,使用卡尔曼滤波器进行跟踪。

质心跟踪算法:质心跟踪算法是一种易于理解且非常有效的算法。这是一个多步骤的过程。

步骤 1:获取检测到的对象的边界框坐标并使用边界框的坐标计算质心。

步骤 2:对于每个后续帧,它使用边界框坐标计算质心,并为这些边界框分配一个 id,并计算每个可能的质心之间的欧几里德距离。

步骤 3:我们的假设是给定对象可能会在后续帧中移动,并且它们质心之间的欧几里德距离将是与其他对象相比的最小距离。

步骤 4:将相同的 ID 分配给后续帧之间的最小移动质心。

为了检测任何运动物体,我们可以用 frame(t) 减去 frame(t+1)。

对象跟踪的应用

因为计算机不断增长的计算能力,对象跟踪变得越来越先进。对象跟踪有一些主要的用例。

  • 交通跟踪和避免碰撞。
  • 人群追踪
  • 无人在家时进行宠物追踪
  • 导弹跟踪
  • 空气画笔

实现欧几里得距离跟踪器

本文使用的所有代码的源文件和测试视频都可以通过这个链接下载

上面讨论的所有步骤都可以使用一些数学计算来执行

我们已经建立了一个名为EuclideanDistTracker对象跟踪的类。

import math
class EuclideanDistTracker:
    def __init__(self):
        # Storing the positions of center of the objects
        self.center_points = {}
        # Count of ID of boundng boxes
        # each time new object will be captured the id will be increassed by 1
        self.id_count = 0
    def update(self, objects_rect):
        objects_bbs_ids = []
        # Calculating the center of objects
        for rect in objects_rect:
            x, y, w, h = rect
            center_x = (x + x + w) // 2
            center_y = (y + y + h) // 2
            # Find if object is already detected or not
            same_object_detected = False
            for id, pt in self.center_points.items():
                dist = math.hypot(center_x - pt[0], center_y - pt[1])
                if dist < 25:
                    self.center_points[id] = (center_x, center_y)
                    print(self.center_points)
                    objects_bbs_ids.append([x, y, w, h, id])     
                    same_object_detected = True
                    break
           # Assign the ID to the detected object
           if same_object_detected is False:
               self.center_points[self.id_count] = (center_x, center_y)                      
               objects_bbs_ids.append([x, y, w, h, self.id_count])       
               self.id_count += 1
        # Cleaning the dictionary ids that are not used anymore
        new_center_points = {}
        for obj_bb_id in objects_bbs_ids:
            var,var,var,var, object_id = obj_bb_id
            center = self.center_points[object_id]
            new_center_points[object_id] = center
       # Updating the dictionary with IDs that is not used
       self.center_points = new_center_points.copy()
       return objects_bbs_ids

你可以创建一个名为tracker.py并粘贴跟踪器代码的文件,也可以使用此链接直接下载跟踪器文件。

  • update→更新方法需要一个包含所有边界框坐标的数组。
  • tracker 返回一个包含 [x,y,w,h, object_id] 的数组。这里 x,y,w,h 是边界框的坐标,object_id 是与该边界框关联的 id。

在准备好跟踪器文件后,我们需要实现我们的目标检测器,稍后我们将我们的跟踪器与目标检测器绑定。

加载库和视频

从我们已经创建的 tracker.py 文件中导入我们的 EuclideanDistTracker 类。

import cv2
import numpy as np
from tracker import EuclideanDistTracker
tracker = EuclideanDistTracker()
cap  = cv2.VideoCapture('highway.mp4')
ret, frame1 = cap.read()
ret, frame2 = cap.read()

cap.read()它返回帧和布尔值,我们需要捕获帧。

在OpenCV中获取视频帧

这个想法是获得两个后续帧之间的绝对差,以便检测移动对象。

while cap.isOpened():
    # ret, frame = cap.read()
    diff = cv2.absdiff(frame1, frame2)  
    # this method is used to find the difference bw two  frames
    gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)
    blur = cv2.GaussianBlur(gray, (5,5), 0 )
    # here i would add the region of interest to count the single lane cars
    height, width = blur.shape
    print(height, width)
    # thresh_value = cv2.getTrackbarPos('thresh', 'trackbar')
    _, threshold = cv2.threshold(blur, 23, 255, cv2.THRESH_BINARY)
    dilated = cv2.dilate(threshold, (1,1), iterations=1)
    contours, _, = cv2.findContours(dilated, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    detections = []
    # DRAWING RECTANGLE BOX (Bounding Box)
    for contour in contours:
        (x,y,w,h) = cv2.boundingRect(contour)
        if cv2.contourArea(contour) <300:
            continue
        detections.append([x,y,w,h])
    boxes_ids = tracker.update(detections)
    for box_id in boxes_ids:
        x,y,w,h,id = box_id
        cv2.putText(frame1, str(id),(x,y-15),  cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0,0,255), 2)
        cv2.rectangle(frame1, (x,y),(x+w, y+h), (0,255,0), 2)
        cv2.imshow('frame',frame1)
    frame1 = frame2
    ret, frame2 = cap.read()
    key = cv2.waitKey(30)
    if key == ord('q):
        break
cv2.destroyAllWindows()

cv2.absdiff 此方法用于获取两帧之间的绝对差。

得到帧差后将差值转换为灰度,然后应用阈值和轮廓检测。

找到的轮廓是所有运动物体的轮廓

为了避免所有的噪音,我们只采用那些尺寸大于 300 的轮廓。

boxes_ids 包含 (x,y,w,h,id)。

cv2.putText 用于在框架上写入 Id。

cv2.rectange() 用于绘制边界框。

输出:车辆计数器系统

结论

在本文中,我们讨论了对象跟踪的概念和对象跟踪的用例,即车辆计数器。

我们讨论了对象跟踪的一些应用,并讨论了质心跟踪算法中涉及的步骤,并将其用于车辆计数。

基于深度学习的对象跟踪算法(如用于 YOLO 对象检测的 DEEP SORT 算法)在我们的案例中执行得更准确。

到此这篇关于Python+OpenCV编写车辆计数器系统的文章就介绍到这了,更多相关Python OpenCV车辆计数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python中单、双下划线的区别总结

    Python中单、双下划线的区别总结

    这篇文章主要给大家介绍了关于Python中单、双下划线区别的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-12-12
  • 如何理解Python中包的引入

    如何理解Python中包的引入

    在本篇文章里小编给各位分享的是一篇关于Python中包的引入详解内容,需要的朋友们可以参考学习下。
    2020-05-05
  • PyTorch如何限制CPU线程数目

    PyTorch如何限制CPU线程数目

    这篇文章主要介绍了PyTorch如何限制CPU线程数目问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-02-02
  • 手把手教你使用Python解决简单的zip文件解压密码

    手把手教你使用Python解决简单的zip文件解压密码

    本文主要介绍了Python解决简单的zip文件解压密码,使用的核心模块是python标准库中的zipfile模块。具有一定的参考价值,感兴趣的可以了解一下
    2021-11-11
  • python虚拟环境的安装和配置(virtualenv,virtualenvwrapper)

    python虚拟环境的安装和配置(virtualenv,virtualenvwrapper)

    这篇文章主要介绍了python虚拟环境的安装和配置(virtualenv,virtualenvwrapper),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Python第三方库face_recognition在windows上的安装过程

    Python第三方库face_recognition在windows上的安装过程

    今天为大家介绍下face recognition在Windows系统上安装与使用,但在Windows平台上face recognition性能会有所下降
    2019-05-05
  • 深入解析Python中filter函数的使用

    深入解析Python中filter函数的使用

    在Python中,filter函数是一种内置的高阶函数,它能够接受一个函数和一个迭代器,然后返回一个新的迭代器,本文主要来介绍一下Python中filter函数的具体用法,需要的可以参考一下
    2023-07-07
  • python 数字类型和字符串类型的相互转换实例

    python 数字类型和字符串类型的相互转换实例

    今天小编就为大家分享一篇python 数字类型和字符串类型的相互转换实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • Python实战项目之MySQL tkinter pyinstaller实现学生管理系统

    Python实战项目之MySQL tkinter pyinstaller实现学生管理系统

    读万卷书不如行万里路,只学书上的理论是远远不够的,只有在实战中才能获得能力的提升,本篇文章手把手带你用MySQL、tkinter、 pyinstaller实现一个学生管理系统,大家可以通过案例查缺补漏,提升水平
    2021-10-10
  • Python selenium模块实现定位过程解析

    Python selenium模块实现定位过程解析

    这篇文章主要介绍了python selenium模块实现定位过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07

最新评论