ValueError:在将再识别的余弦距离与IoU矩阵结合用于自定义多目标跟踪时,形状不匹配
我正在使用Python、OpenCV和 TensorFlow构建一个定制的多对象跟踪(MOT)系统。我的目标是跟踪人并进行实时衣物识别。为了在一个人转身时防止ID切换(因为这会显著改变他们的衣物特征),我正在实现一个类似DeepSORT的自定义匹配级联。
我希望使用一个加权成本矩阵,将Re-ID特征的余弦距离与边界框IoU结合起来,将现有轨迹与新的检测关联起来:

然而,我在计算最终的成本矩阵时遇到了一个 ValueError 相关的问题。
代码:
以下是我的匹配逻辑的最小可复现示例。track_features 是特征的历史库,det_features 则是从我的TensorFlow模型中提取的。
import numpy as np
from scipy.spatial.distance import cdist
import tensorflow as tf
def compute_cost_matrix(track_features, det_features, track_boxes, det_boxes, alpha=0.5):
# track_features shape: (N, 128) - N is number of active tracks
# det_features shape: (M, 128) - M is number of new detections (TensorFlow output)
# 1. Calculate Re-ID Cosine Distance
# Convert TF tensor to numpy for scipy
det_features_np = det_features.numpy() if tf.is_tensor(det_features) else det_features
reid_dist = cdist(track_features, det_features_np, metric='cosine') # Expected shape: (N, M)
# 2. Calculate IoU Distance (1 - IoU)
# compute_iou is a custom function returning an (N, M) numpy array
iou_matrix = compute_iou(track_boxes, det_boxes)
iou_dist = 1.0 - iou_matrix # Expected shape: (N, M)
# 3. Combine them
# THIS IS WHERE THE ERROR OCCURS
cost_matrix = alpha * reid_dist + (1 - alpha) * iou_dist
return cost_matrix
# Mock data to reproduce the issue
N, M = 5, 3
track_feats = np.random.rand(N, 128)
det_feats = tf.random.normal((M, 128)) # Extracted from TF model
t_boxes = np.random.rand(N, 4)
d_boxes = np.random.rand(M, 4)
# Run the function
cost = compute_cost_matrix(track_feats, det_feats, t_boxes, d_boxes)
错误信息:ValueError: operands could not be broadcast together with shapes (5,3) and (5,)
我已尝试过:
- 我已验证
reid_dist能成功输出形状为(5, 3)。 - 我检查了
compute_iou函数。当M=0(帧中没有检测结果)时,我添加了一个保护条件,返回一个空数组,这样就能正常工作。 - 我怀疑问题要么出在
alpha的标量乘法在矩阵上的广播方式,要么我的compute_iou函数在评估边界框时不知为何返回了形状为(5,)的一维数组,而不是形状为(5, 3)的二维矩阵,但我不确定如何在动态对齐这些形状时确保安全。
无论跟踪数N 和检测数M 如何波动,如何正确对齐并将这两种距离度量结合起来?
(编辑:添加MRE)
下面是一个使用 numpy 来模拟特征提取和边界框数据的独立脚本。你可以直接复制粘贴并运行它,以复现我所遇到的 ValueError。
import numpy as np
from scipy.spatial.distance import cdist
# --- 1. MOCK DATA (Minimal & Reproducible) ---
# 假設畫面中有 5 個追蹤中的人 (Tracks),以及 3 個新偵測到的人 (Detections)
num_tracks = 5
num_detections = 3
feature_dim = 128
# 使用隨機矩陣模擬 TensorFlow 輸出的 Re-ID 特徵
track_features = np.random.rand(num_tracks, feature_dim)
det_features = np.random.rand(num_detections, feature_dim)
# 使用隨機數值模擬 YOLO 輸出的 Bounding Boxes [x1, y1, x2, y2]
track_boxes = np.random.rand(num_tracks, 4) * 100
det_boxes = np.random.rand(num_detections, 4) * 100
# --- 2. MY LOGIC (Where the error happens) ---
def compute_cost_matrix(t_feats, d_feats, t_boxes, d_boxes, alpha=0.5):
# Step A: 成功算出 Re-ID 距離矩陣,形狀為 (5, 3)
reid_dist = cdist(t_feats, d_feats, metric='cosine')
# Step B: 假設這是我的 IoU 計算邏輯,但它回傳了錯誤的形狀 (例如 1D array)
# 這裡故意只回傳 (5,) 的形狀,模擬實際開發中常遇到的維度丟失問題
iou_dist = np.random.rand(num_tracks)
# Step C: 嘗試將兩者加上權重合併 -> 這裡會觸發 ValueError!
cost_matrix = alpha * reid_dist + (1 - alpha) * iou_dist
return cost_matrix
# --- 3. RUN IT ---
if __name__ == "__main__":
# 執行函數,將會拋出形狀不匹配的錯誤
final_cost = compute_cost_matrix(track_features, det_features, track_boxes, det_boxes)
print("Cost Matrix:", final_cost)
解决方案
正如你已经怀疑的那样,问题出在一维 iou_dist 与二维 reid_dist 之间的广播。Numpy能够 从右向左广播到正确的维度。不过,在你的情况下,维度对齐错误,因此numpy无法广播。
在你的情形中,不匹配的情况在 某个图示 中有说明:
这可以通过在cost_matrix计算时 添加一个新维度 来实现,以便对齐数组以进行广播:
cost_matrix = alpha * reid_dist + (1 - alpha) * iou_dist[:, np.newaxis]
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。
