【发布时间】: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 链接...
如果有人能找出答案,请告诉我。只是希望有解决方案。 提前致谢。
【问题讨论】:
-
要成功地做到这一点,您需要一个合适的对象跟踪算法。查找质心最小距离。这可能会帮助你github.com/lev1khachatryan/Centroid-Based_Object_Tracking
-
我认为为每个被跟踪对象分配一个唯一的ID,然后在汽车或车辆进入检测区域时检查ID,可以避免两次检测到单车。
标签: python opencv computer-vision increment yolo