如何在没有校准的情况下获得被跟踪物体的速度?

How do I get the velocity of a tracked object without calibration?

我正在使用 YoloV4 和 Deepsort 来检测和跟踪帧中的人。

我的目标是在没有校准的情况下以有意义的单位获得移动的人的速度,因为我希望能够将带有此模型的相机移动到不同的房间而不必每次都进行校准。我理解这是一个非常困难的问题。我目前正在以每秒像素的速度获得速度。但这是不准确的,因为靠近框架的项目“移动”得更快。

我的问题是我是否可以使用人员检测的边界框作为以像素为单位的人员大小的测量值,以及我是否可以平均一个人的大小(比如 68 英寸高 x 15 英寸宽) ) 并具有必要的“校准”指标来确定 inches/s 对象从框架中的 A 点移动到 B 点,作为从区域 A 到区域 B 的人的大小的反映?

简而言之,有没有一种方法可以根据物体的大小获得速度,以确定它在一帧中的移动速度?

任何建议都会有所帮助! 谢谢!

这就是我现在计算速度的方式。


# # Calculate the center of the bounding box
xCenter = int((bbox[0] + bbox[2]) / 2)
yCenter = int((bbox[1] + bbox[3]) / 2)

# Get metrics from metrics {track_id : [[frames, xCenter, yCenter], [frames, xCenter, yCenter]] }
values = metrics[track_id]

# # calculate displacement, velocity and speed.
if len(values) > 1:
    delta_frames = values[-1][0] - values[-2][0]
    delta_t = delta_frames / fps     #fps = 30
    delta_x = values[-1][1] - values[-2][1]
    delta_y = values[-1][2] - values[-2][2]

    total_displacement = math.sqrt(delta_x ** 2 + delta_y ** 2)

    speed = total_displacement / delta_t

我想这就是我一直在寻找的答案。

我计算边界框的高度和宽度。我通过将边界框除以平均人类高度和宽度来得到该边界框的每英寸像素数。然后我将区域 A 的每英寸像素与区域 B 的每英寸像素之间的 linspace() 求和以获得距离。虽然它不是很准确,所以也许我可以以某种方式改进它。

误差主要来自边界框。看起来边界框从上到下很好,但从左到右(宽度)不太好,因为它考虑到了手臂和腿。我要看看我是否可以仅使用人头检测作为测量。

# # Average human dimensions in inches
avg_person_width = 15
avg_person_height = 65

# # width, Height of the bounding box in pixels
bbox_width = bbox[2] - bbox[0]
bbox_height = bbox[3] - bbox[1]

# Pixels per inch within the bounding box
pixels_per_inch_width = bbox_width / avg_person_width
pixels_per_inch_height = bbox_height / avg_person_height

if track.track_id in metrics:
# append the new number to the existing array at this slot
    metrics[track_id].append([frame_idx, xCenter, yCenter, pixels_per_inch_width, pixels_per_inch_height])
else:
    # create a new array in this slot
    metrics[track_id] = [[frame_idx, xCenter, yCenter, pixels_per_inch_width, pixels_per_inch_height]]

values = metrics[track_id]

# # calculate displacement, velocity and speed.
if len(values) > 1:
    if all(values[-1]) and all(values[-2]):
        delta_frames = values[-1][0] - values[-2][0]
        delta_t = delta_frames / fps
        delta_x = values[-1][1] - values[-2][1]
        delta_y = values[-1][2] - values[-2][2]

        pixels_per_inch_width = values[-1][3]
        pixels_per_inch_height = values[-1][4]

        pixels_per_inch_width_2 = values[-2][3]
        pixels_per_inch_height_2 = values[-2][4]

        distance_x = np.linspace(pixels_per_inch_width, pixels_per_inch_width_2, abs(delta_x))
        distance_y = np.linspace(pixels_per_inch_height, pixels_per_inch_height_2, abs(delta_y))

        total_distance_x = sum(distance_x)
        total_distance_y = sum(distance_y)

        total_displacement = math.sqrt(total_distance_x ** 2 + total_distance_y ** 2)

        # # Inches / second (IPS)
        speed_ips = total_displacement / delta_t

        '''
        conversion: 1 inch per second (in/s) = 0.056818182 mile per hour (mph)
        '''
        # # Miles / Hour. Average human walks at < 3 mph
        speed_mph = speed_ips * 0.056818182