yolov3-archive detect 和 test 输出的结果不一,以及test检测结果P有误差的原因

问题出在数据集的调用

detect 文件调用的是LoadImage:

dataset = LoadImages(source, img_size=img_size)

test文件调用的是LoadImagesAndLabels:

dataset = LoadImagesAndLabels(path, img_size, batch_size, rect=False, single_cls=opt.single_cls)
# 此处我为了直接对比 detect 和 test 将 rect 默认设为了 False

首先两者在调用letterbox函数修整图片时有区别:

LoadImages会默认使用Auto参数减少pad量,将pad控制在64以下。

而LoadImagesAndLabels会默认禁用Auto,并且将scale_up参数改为由参数augment操控,

后者仅对小图有不同效果,而前者会导致此处会导致输入网络的图片大小不同

所以将LoadImagesAndLabels中的letterbox调用改为了:

img, ratio, pad = letterbox(img, shape, auto=True, scaleup=True)

其次LoadImagesAndLabels读取图片会调用load_image函数:

这是罪魁祸首

在这里插入图片描述

538行的int操作会导致 w0 * r 自动进行 ceil 操作向下取整, 导致大于小数0.5的尺寸resize shape 小1

图片本体会被缩小1个像素,对于小目标影响明显。

在这里插入图片描述
LoadImage的图片读取就没这么多花

将有问题的那一行修改成这样就好了:

img = cv2.resize(img, (int(round(w0 * r)), int(round(h0 * r))), interpolation=interp)

再次检查,发现还有问题

result.json文件里所有predictionx方向上的坐标都不多不少大了2

result.json
result.json
detect输出的结果
来自detect自写代码直接输出的结果

检查发现,两者在调用scale_coords函数上存在区别,

detect未传入ratio_pad参数,test使用数据集中的过来的shape作为ratio_pad。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在第一个if中,detect走的是第一条路直接根据长边计算gain,再计算pad

在test中,此时如果shape[0][0]不等于shape[0][1],两者的gain计算就会出现偏差,

而shape[0][0]正是高度方向的shape。

解决方案是修改scale_coords函数:

def scale_coords(img1_shape, coords, img0_shape, ratio_pad=None):
    # Rescale coords (xyxy) from img1_shape to img0_shape
    if ratio_pad is None:  # calculate from img0_shape
        gain = max(img1_shape) / max(img0_shape)  # gain  = old / new
        pad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2  # wh padding
    else:
        gain = ratio_pad[0]  # 在此处读取整个shape[0]
        pad = ratio_pad[1]

    coords[:, [0, 2]] -= pad[0]  # x padding
    coords[:, [1, 3]] -= pad[1]  # y padding
    if ratio_pad is None:
        coords[:, :4] /= gain
    else:
        coords[:, [0, 2]] /= gain[1]  # 在此处分别对x和y进行缩放
        coords[:, [1, 3]] /= gain[0]
    clip_coords(coords, img0_shape)
    return coords

结果对比

修改前:
在这里插入图片描述
修改后:
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值