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函数:

这是罪魁祸首

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

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

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

yolov3-archive detect 和 test 输出的结果不一,以及test检测结果P有误差的原因_第2张图片
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。
在这里插入图片描述

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

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

在第一个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

结果对比

修改前:
yolov3-archive detect 和 test 输出的结果不一,以及test检测结果P有误差的原因_第5张图片
修改后:
yolov3-archive detect 和 test 输出的结果不一,以及test检测结果P有误差的原因_第6张图片

你可能感兴趣的:(yolov3,python,python,pytorch,深度学习)