coco数据集进行裁剪、数据增强过程中的ground_truth bbox的设定以及变化

目录

前言:

1. 写入json文件时的 ground truth bbox

2. 导入图片 和 获取对应的 ground truth bbox

3. 进行数据增强后, 决定了 最终的 ground truth bbox


前言:


数据集的ground truth bbox 是一个重要的部分,在训练过程的开始输入数据会经过一系列的变化,然后才被送入到model中,在这个过程中,ground truth bbox 是怎样对应着 数据的变化而相应的改变,从而达到标注的信息是正确的呢?o(* ̄▽ ̄*)o 

1. 写入json文件时的 ground truth bbox

        for trackid, ann in enumerate(anns):  # ann  相当于拿出每张图片的每个目标的bbox
            rect = ann['bbox']  # bbox
            c = ann['category_id']  # 类别 id
            bbox = [rect[0], rect[1], rect[0] + rect[2], rect[1] + rect[3]]  # xywh to xyxy
            if rect[2] <= 0 or rect[3] <= 0:  # lead nan error in cls.
                count += 1
                print(count, rect)
                continue
            dataset[video_crop_base_path]['{:02d}'.format(trackid)] = {'000000': bbox}  # 举例 {'val2017/000000397133':{'00':{'000000':[217.62,240.54,256.61,298.289999]}}}

可以看出,虽然数据集中的每张图片被裁剪成以目标为中心并resize成511(详见另一篇用于目标跟踪的COCO数据集的预处理过程的API,以及对训练数据的数据增强操作),但是写入json文件的ground truth bbox 还是原来最初标注的bbox值,没做任何处理,只不过从xywh转成xyxy型写入的,所以经过裁剪处理后的图片与json文件中的ground truth bbox 并不是 对应的,但是依然可以获取一些原始的信息,比如bbox的 长和宽,以及会根据这个原始的bbox 来计算填充裁剪bbox的尺寸

利用创建的json文件中的bbox可视化效果如下,可见其包含的信息还是原来未处理中的目标

coco数据集进行裁剪、数据增强过程中的ground_truth bbox的设定以及变化_第1张图片

 裁剪后图片画json文件中的bbox

coco数据集进行裁剪、数据增强过程中的ground_truth bbox的设定以及变化_第2张图片

 裁剪前的原始图片画json文件中的bbox

2. 导入图片 和 获取对应的 ground truth bbox

由于裁剪的图片都是以目标为中心的,所以根据裁剪图片的形状可以确定目标的中心坐标。然后虽然裁剪的时候尺寸不一定是设定的255和127,不过最终确定的模板和搜索区域的输入是确定的,即127和255。所以根据这个,可以获得目标的 ground truth bbox,目标的中心坐标就是图片的中心坐标,目标的 w 和 h  可以根据裁剪 bbox(填充后的尺寸和resize后的输入尺寸的比例)和json文件中的ground truth bbox 得到的w和h 得到,如下代码中所示

    def _get_bbox(self, image, shape):  # shape 就是 bbox
        imh, imw = image.shape[:2]  # 511,511
        if len(shape) == 4:  # True
            w, h = shape[2]-shape[0], shape[3]-shape[1]  # 举例 h:42.920000000000016  w:38.360000000000014
        else:
            w, h = shape
        context_amount = 0.5
        exemplar_size = cfg.TRAIN.EXEMPLAR_SIZE  # 127
        wc_z = w + context_amount * (w+h)  # 举例 79.0000000000000
        hc_z = h + context_amount * (w+h)  # 举例 83.5600000000000
        s_z = np.sqrt(wc_z * hc_z)  # 举例 81.248015367668   裁剪填充的尺寸
        scale_z = exemplar_size / s_z  # 举例 1.5631115104248  ratio
        w = w*scale_z  # 举例 59.96150953989797  裁剪的尺寸 w 以及 h
        h = h*scale_z  # 举例 67.08890002743356
        cx, cy = imw//2, imh//2  # 举例 cx:255 cy : 255  以目标为中心
        bbox = center2corner(Center(cx, cy, w, h))  # {corner:4}   原矩形框没有用上,只用了w和w计算一下比例,然后目标中心就是511图片的中心
        return bbox

但这个bbox 是对应 裁剪后的满足输入到model  尺寸的image的标注,到现在为止只是导入了原来裁剪后的图片,还没进行 填充 再 resize成 127和255 这步操作,所以现在 image 和 ground truth bbox 也不是 对应的

在 iamge 上画一下 现在的 ground truth bbox,如下所示,虽然框住的目标是正确的,但实际上现在还不算是紧密的矩形框,简单来说中心位置是正确的,但是size是不对应的,该图片还没进行填充裁剪和resize操作(现在的尺寸依然是511),这个图中的目标太小体现不出来差别。

coco数据集进行裁剪、数据增强过程中的ground_truth bbox的设定以及变化_第3张图片

3. 进行数据增强后, 决定了 最终的 ground truth bbox

到现在 ,image的尺寸依然是(511,511),进入数据增强,首先会设定一个新的crop_bbox(后面会以这个为基础构建变换矩阵, 对 image 进行 放射变换),以目标为中心,template_size 或者 search_size为边长,

shape = image.shape  # (511,511,3)
crop_bbox = center2corner(Center(shape[0]//2, shape[1]//2,
                                         size-1, size-1))

将其 (蓝色)与第2部分得到的ground truth bbox (黄色) 一起画出来如下所示 

coco数据集进行裁剪、数据增强过程中的ground_truth bbox的设定以及变化_第4张图片

 数据增强过程中,只有 平移和尺度变换会改变bbox的位置和尺寸,所以这步过后最终的ground turt bbox才确定下来。

进行平移和尺度变换后的矩形框如下图红色所示。它是根据上图蓝色部分基础上进行的平移加变换。画出来后如下图所示。,其中红色就是平移加尺度变换后的裁剪bbox

coco数据集进行裁剪、数据增强过程中的ground_truth bbox的设定以及变化_第5张图片

 那么裁剪bbox进行平移和尺度变换后,裁剪的图片也会相比于原本打算的会发生变化,接下来就是怎样把目标的 ground turth bbox 也进行相应的变换,是目标与 ground turth bbox 对应,进行如下操作:

x1, y1 = crop_bbox.x1, crop_bbox.y1
bbox = Corner(bbox.x1 - x1, bbox.y1 - y1,
                      bbox.x2 - x1, bbox.y2 - y1)
if self.scale:
    bbox = Corner(bbox.x1 / scale_x, bbox.y1 / scale_y,
                          bbox.x2 / scale_x, bbox.y2 / scale_y)

在未裁剪的image 画出 bbox如下所示

coco数据集进行裁剪、数据增强过程中的ground_truth bbox的设定以及变化_第6张图片

 如图中左上角矩形框所示,这是为裁剪图片,但是如果把红色矩形框的左上角顶点移到图片image的左上角顶点上,是不是可以想象出它已经包围了目标。其实源代码中也是这样做的,从上面的代码中就可以看出,就是相当于把 进行尺度变换后的用于裁剪的bbox(红色框)左上角顶点(x1, y1)作为参照对应到图片的左上角顶点(0,0),用ground turth bbox(黄色框所示)的左上角顶点和右下角顶点减去(x1, y1)。

接下来把image 进行裁剪,裁剪成127或者255,

    def _crop_roi(self, image, bbox, out_sz, padding=(0, 0, 0)):
        bbox = [float(x) for x in bbox]  # list:4 [, , ,]
        a = (out_sz-1) / (bbox[2]-bbox[0])
        b = (out_sz-1) / (bbox[3]-bbox[1])
        c = -a * bbox[0]
        d = -b * bbox[1]
        mapping = np.array([[a, 0, c],
                            [0, b, d]]).astype(np.float)
        crop = cv2.warpAffine(image, mapping, (out_sz, out_sz),
                              borderMode=cv2.BORDER_CONSTANT,
                              borderValue=padding)

以红色矩形框为基础,设置变换矩阵,进行仿射变换,得到相应的输出尺寸,裁剪后的图片上画出ground turth bbox 如下图所示,可以以看到下面就是最终的 search图片和 ground turth bbox 的由来。

coco数据集进行裁剪、数据增强过程中的ground_truth bbox的设定以及变化_第7张图片

这里会有一个疑问,不仅search会进行平移加尺度变换 ,而且模板template也会进行平移加尺度变换,那模板的目标会相对于整个区域发生偏移吗?的确模板很可能不在以目标为中心,不过这无关紧要,因为模板送入model的作用就是整个作为卷积核去对大的搜索区域进行相关运算,所以目标在不在中心不影响它应尽的作用,而且这样也增加了模板的多样性以及model的鲁棒性。

 template, _ = self.template_aug(template_image,
                                        template_box,
                                        cfg.TRAIN.EXEMPLAR_SIZE,
                                        gray=gray)  # ndarry:(127,127,3)

 search, bbox = self.search_aug(search_image,
                                       search_box,
                                       cfg.TRAIN.SEARCH_SIZE,
                                       gray=gray) 

你可能感兴趣的:(大数据)