main.c_cursor
if (1) {
initMult_yolov5params(&obj->yolov5params);
/* 兜底:确保解码使用的输入尺寸有效 */
obj->yolov5params.inWidth[0] = obj->ioBufDesc.inWidth[0];
obj->yolov5params.inHeight[0] = obj->ioBufDesc.inHeight[0];
// 添加调试:打印所有输出张量的维度信息
// printf("=== 开始处理YOLOv5检测头 ===\n");
// for(int zh_idx = 0; zh_idx < 5; zh_idx++) // 查看所有5个输出张量
详细解释下为什么原本的代码中inWidth[0]/inHeight[0] 没正确设置就会遇到我的这个问题,以及你是怎么解决的,为什么这样有用
原因和现象是匹配的:
- 解码里用的是 inWidth[0]/inHeight[0] 作为“输入图像尺寸”来还原坐标,包括 box 的 x/y 和车位四个角点。坐标计算是「网络输出的相对坐标 × 输入尺寸」的形式。
- 你现在只给 yolov5params 的 1~3 号 head 赋值,inWidth[0]/inHeight[0] 没有被赋值(可能是 0、旧值 544×480 或未初始化随机值)。
- 一旦 inWidth[0]/inHeight[0] 比真实输入小,所有解码坐标都会被 按比例缩小,因此视觉上会全部挤在左上角;如果是 0,坐标直接趋近 0,更明显地聚到左上角。
- rm/fsd 没问题是因为它们用的是自己的输入/输出尺寸,不依赖 inWidth[0]。
我做的修复:
1) 在 main.c 里显式兜底赋值
在 initMult_yolov5params() 后加了:
yolov5params.inWidth[0] = ioBufDesc.inWidth[0];
yolov5params.inHeight[0] = ioBufDesc.inHeight[0];
这样不管 head 索引怎么填,inWidth[0] 都是正确的输入尺寸。
2) 在解码里优先用 inWidth[head_idx]/inHeight[head_idx],若无则回退到 [0]
这样即使只给当前 head 填了尺寸,解码也能用到正确的输入尺寸,不会再被错误缩放。
为什么有用:解码坐标的核心就是“相对坐标 × 输入尺寸”。输入尺寸一旦错,就会整体缩放到错误的位置。把 inWidth/inHeight 保证为真实输入分辨率(736×608),坐标就能恢复到正确尺度,车位不再堆在左上角。
我已在 mult_yolov5_post_copy.c 修正了第 1 点:解码时不再固定用 inWidth[0]/inHeight[0],而是优先用当前 head 的 inWidth[head_idx]/inHeight[head_idx],如果为 0 再回退到 [0]。这样即使 main.c 没给 [0] 赋值,也不会把坐标缩到左上角。
修改位置在 getMult_yolov5e2eResult() 中,新增了 in_w/in_h,并替换所有坐标缩放与关键点计算的输入尺寸。
你可以直接重新跑一版,psd 可视化应恢复正常。
如果还想彻底兜底,也可以在 main.c 里给 yolov5params.inWidth[0]/inHeight[0] 显式赋值为输入尺寸(736/608),我也可以顺手帮你加。
我看了 main.c 和 mult_yolov5_post_copy.c,最可疑的是 输入宽高没正确传到解码函数,导致坐标按 0 或旧尺寸缩放,结果集中在左上角。
关键点:
- 你现在只给 zh_idx = 1..3 填了 yolov5params,但解码里用的是 inWidth[0] / inHeight[0],这两个很可能没被赋值(或仍是旧值),所以坐标被缩小到左上角。
main.cLines 1088-1118
// ...
for(int zh_idx = 1; zh_idx < 4; zh_idx++)
{
obj->yolov5params.scale[zh_idx] = obj->out_args.scale[zh_idx];
obj->yolov5params.outWidth[zh_idx] = obj->ioBufDesc.outWidth[zh_idx];
obj->yolov5params.outHeight[zh_idx] = obj->ioBufDesc.outHeight[zh_idx];
obj->yolov5params.inWidth[zh_idx] = obj->ioBufDesc.inWidth[zh_idx];
obj->yolov5params.inHeight[zh_idx] = obj->ioBufDesc.inHeight[zh_idx];
// ...
}
mult_yolov5_post_copy.cLines 307-316
float x = (float)raw_data[obj_x_idx] / yolov5params->scale[head_idx];
x = (x * 2.0 - 0.5 + w_idx) * (float)(yolov5params->inWidth[0]) / (float)(yolov5params->outWidth[head_idx]);
float y = (float)raw_data[obj_y_idx] / yolov5params->scale[head_idx];
y = (y * 2.0 - 0.5 + h_idx) * (float)(yolov5params->inHeight[0]) / (float)(yolov5params->outHeight[head_idx]);
只要 inWidth[0]/inHeight[0] 没正确设置,就会出现“全部挤在左上角”。
建议你先做以下排查(不改代码也能确认):
1) 打印 yolov5params.inWidth[0]/inHeight[0],看是否为 736/608。
2) 确认输出 tensor 的顺序 是否变化了:新模型可能改变了输出顺序,导致你把检测头当成分割头或反之。你已经留了调试打印(被注释),可以打开看每个 outWidth/outHeight/outNumChannels,确认检测头是哪几个索引。
3) 检查 anchors 是否匹配新模型。如果新模型重新聚类了 anchors,但代码仍用旧 anchors,也会导致坐标异常(虽然一般不会全部集中到左上角,但也会严重偏移)。
如果确认是第 1 条导致,修复思路是:让 yolov5params->inWidth[0]/inHeight[0] 始终等于输入图像大小(比如用 ioBufDesc.inWidth[0]/inHeight[0] 直接赋值),或者在解码里改用 inWidth[head_idx] 并确保每个 head 的 inWidth 都被正确填成输入尺寸。
你要我帮你把代码改掉的话,告诉我你现在检测头对应的输出索引(1..3 是否正确),我可以直接改好。
更多推荐

所有评论(0)