【问题标题】:How to count each vehicle only once in Traffic vehicle counter?如何在交通车辆计数器中只计算每辆车一次?
【发布时间】:2021-09-06 05:48:37
【问题描述】:

我正在使用 yolov4 和 opencv 来检测车辆并在示例视频中跟踪它们。但问题是,在我的代码只占用一辆车并在每一帧中将其视为一辆新车之前,因为它通过视频并且它增加了 1 到汽车计数。因此,只有一辆车被计算了 5 或 6 次。然后我尝试了这个方法:

if 387<bbox[0]<400: # bbox[0] is the top left coordinate of the car's bounding box
    car_count += 1 # if the top left coordinate of the car's bounding box is within the range, then increment 1 to car_count

简而言之,我确定了汽车的检测范围。但同样如此,如果汽车仍然行驶得较慢,或者如果它没有在 1 帧内通过范围,那么汽车会被计算两次。如果我缩小范围,有时在 15-20 fps 范围内,如果汽车错过了检测范围或汽车开得太快,那么 car_counter 不会增加 1。那么,知道如何解决这个问题吗?

示例图片:

两条红线之间的区域是样本图像中帧的检测范围。 那么,我可以让汽车在进入检测范围后只被检测一次吗?

更新:我刚刚想出了如何在汽车边界框的中间绘制圆圈。所以我可以得到每个边界框的中点。 我通过使用:

import numpy as np
# coor[0], coor[1], coor[2], coor[3] = (xmin, ymin, xmax, ymax); 4 points of a bounding box
x, y = (coor[0]+coor[2]) // 2, (coor[1]+coor[3]) // 2
x = np.round(x).astype("int")
y = np.round(y).astype("int")
cv2.circle(image, (x, y), 10, (255, 255, 0), cv2.FILLED)

我认为我们可以只跟踪这些中间点,而不是跟踪边界框的一个角。

在边界框中带有中心圆的图像

汽车上的黄色圆圈是边界框的中心。

编辑:这是脚本:

x, y = (coor[0]+coor[2]) // 2, (coor[1]+coor[3]) // 2
x = np.round(x).astype("int")
y = np.round(y).astype("int")
if class_name == 'car':
    if 390.0<x<400.0:
        car_count += 1
        with open("results.txt", "a") as result_file:
            result_file.write(f"Cars: {car_count};Motorbikes: {motorbike_count};Bicycles: {bicycle_count};Trucks: {truck_count}\n")
        print("Car detected !")

if class_name == 'motorbike':
    if 390.0<x<400.0:
        motorbike_count += 1
        with open("results.txt", "a") as result_file:
            result_file.write(f"Cars: {car_count};Motorbikes: {motorbike_count};Bicycles: {bicycle_count};Trucks: {truck_count}\n")
        print("Motorbike detected !")

if class_name == 'bicycle':
    if 390.0<x<400.0:
        bicycle_count += 1
        with open("results.txt", "a") as result_file:
            result_file.write(f"Cars: {car_count};Motorbikes: {motorbike_count};Bicycles: {bicycle_count};Trucks: {truck_count}\n")
        print("Bicycle detected !")

if class_name == 'truck':
    if 390.0<x<400.0:
        truck_count += 1
        with open("results.txt", "a") as result_file:
            result_file.write(f"Cars: {car_count};Motorbikes: {motorbike_count};Bicycles: {bicycle_count};Trucks: {truck_count}\n")
        print("Truck detected !")

这是一种对汽车或车辆进行累积计数的脚本。

第二次编辑:我在 google colab 中运行它,我得到 27-30 FPS。我刚刚检查了质心位置,它们相差大约。每帧 10 个。例如。上一帧:x:682,下一帧:x:673-671之间

第三次编辑:我真的认为我们应该只拿一辆车并将其值设置为 not_counted。并且一旦它通过线,它的值将是is_counted。如果该值为 is_counted,则不会再次计算同一辆车。这可能有助于解决问题。但现在的问题是如何为每个检测到的对象定义这个值。这是我正在使用的整个代码的 github 链接...

Link to the Repo

如果有人能找出答案,请告诉我。只是希望有解决方案。 提前致谢。

【问题讨论】:

  • 要成功地做到这一点,您需要一个合适的对象跟踪算法。查找质心最小距离。这可能会帮助你github.com/lev1khachatryan/Centroid-Based_Object_Tracking
  • 我认为为每个被跟踪对象分配一个唯一的ID,然后在汽车或车辆进入检测区域时检查ID,可以避免两次检测到单车。

标签: python opencv computer-vision increment yolo


【解决方案1】:

为此,您需要一个跟踪器。 tracked 将为每个检测到的对象提供一个 ID,您可以使用跟踪器 ID 检查该区域。我的建议是DeepSort,因为它与 YOLO 完全兼容,并且有很多这两者结合的例子。 Here 是深度排序和 YOLO 结合的一个例子。 如您所见,每个项目都有一个您可以轻松访问的 ID。

【讨论】:

  • 你能给出一个类似的代码示例吗?
  • @Just_A_Coder 我编辑答案并为您附加一个示例。希望对您有所帮助。
  • @Just_A_Coder 有用吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-16
  • 2021-11-05
  • 2020-02-25
  • 1970-01-01
  • 2020-08-02
  • 1970-01-01
相关资源
最近更新 更多