目标检测数据预处理--尺寸变换

目录

1. 比例缩放

2. 使用letterbox


目标检测训练中,我们的数据集尺寸大部分时侯都是不符合网络输入的,需要对尺寸进行修改,下面我介绍两种常用尺寸变换方法:

1. 比例缩放

这种方法就是简单的对图片尺寸进行比例缩放,一般使用cv2.resize()对图片进行缩放,然后计算长宽缩放比例,再通过比例来缩放标注的目标框尺寸。具体代码如下:

def read_and_resize_picture(img_path, img_boxes):
    """
    :function:读取图片,并缩放图片尺寸到指定尺寸,同时修改目标框尺寸
    :param img_path: 单张图片路径
    :param img_boxes: 对应图片目标框[[xmin,ymin,xmax,ymax],...,[xmin,ymin,xmax,ymax]]
    :return:图片(已经读取啦),修改的目标框
    """
    img = cv2.imread(img_path,flags=1)
    height, width = img.shape[0:2]
    if height == 416 and width == 416:
        return img, img_boxes
    else:
        h_s = height / 416.
        w_s = width / 416.
        # box = img_boxes
        # 将原图resize成300,300
        img_resize = cv2.resize(img, dsize=(416, 416), interpolation=cv2.INTER_LINEAR)
        # imgs.append(img_resize)
        img_boxes[:, 0:3:2] = img_boxes[:, 0:3:2] / w_s
        img_boxes[:, 1:4:2] = img_boxes[:, 1:4:2] / h_s
        # boxes.append(box)
        return img_resize, img_boxes

这种方法修改图片尺寸方便,但是会改变图片特征

2. 使用letterbox

先对图片填充黑边,使图片尺寸为正方形,然后再缩放,这样不会改变图片尺寸,代码如下:

import numpy as np
import cv2
import math
def cv2_letterbox_image(image, expected_size, box):
    """
    function:使用letterbox填充并修改图片尺寸
    :param image: 原图
    :param expected_size: 想要修改后的尺寸
    :param box: 原图目标框
    :return: 修改后的图片,目标框
    """
    ih, iw = image.shape[0:2]
    ew, eh = expected_size
    scale = min(eh / ih, ew / iw)
    nh = int(ih * scale)
    nw = int(iw * scale)
    for i in range(4):
        box[i] = box[i] * scale
    image = cv2.resize(image, (nw, nh), interpolation=cv2.INTER_CUBIC)
    top = (eh - nh) // 2
    box[1] = box[1] + top
    box[3] = box[3] + top
    bottom = eh - nh - top
    left = (ew - nw) // 2
    box[0] = box[0] + left
    box[2] = box[2] + left
    right = ew - nw - left
    new_img = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_CONSTANT)
    return new_img, box
def cv2_deletterbox_image(image, current_size, box):
    """
    function:去除图像灰边,并还原目标框尺寸
    :param image: 原图
    :param current_size: 当前图片尺寸(网络输入尺寸)
    :param box: 网络输入尺寸下的目标框
    :return: 匹配原图的目标框
    """
    ih, iw = image.shape[0:2]
    ew, eh = current_size
    scale = min(eh / ih, ew / iw)
    nh = int(ih * scale)
    nw = int(iw * scale)

    top = (eh - nh) // 2
    box[1] = box[1] - top
    box[3] = box[3] - top
    left = (ew - nw) // 2
    box[0] = box[0] - left
    box[2] = box[2] - left
    for i in range(4):
        box[i] = box[i] / scale

    return box
def view_1():
    box = np.array([147, 336, 402, 437])

    ptr1 = (box[0], box[1])
    ptr2 = (box[2], box[3])
    color = (0, 0, 255)
    path = "YOLOV3_high/data/val/JPEG/image_1.jpg"
    img = cv2.imread(path)
    dst_img, box_new = cv2_letterbox_image(img, (415, 415), box)
    cv2.rectangle(img, ptr1, ptr2, color, 2)
    cv2.imshow('src_img', img)
    cv2.rectangle(dst_img, (box_new[0], box_new[1]), (box_new[2], box_new[3]), color, 2)
    cv2.imshow("dst_img", dst_img)
    # cv2.imwrite("pred_img.jpg",dst_img)
    cv2.waitKey(0)
def view_2():
    box = np.array([147, 336, 402, 437])

    ptr1 = (box[0], box[1])
    ptr2 = (box[2], box[3])
    color = (0, 0, 255)
    path = "YOLOV3_high/data/val/JPEG/image_1.jpg"
    img = cv2.imread(path)
    img_src = img.copy()
    dst_img, box_new = cv2_letterbox_image(img, (416, 416), box)
    cv2.rectangle(img, ptr1, ptr2, color, 2)
    cv2.imshow('src_img', img)
    cv2.rectangle(dst_img, (box_new[0], box_new[1]), (box_new[2], box_new[3]), color, 2)
    cv2.imshow("dst_img", dst_img)

    box_src = cv2_deletterbox_image(img_src, (416,416), box_new)
    cv2.rectangle(img_src, (box_src[0], box_src[1]), (box_src[2], box_src[3]), color, 2)
    cv2.imshow("img_src", img_src)
    cv2.waitKey(0)
if __name__ == "__main__":
    # view_1()
    view_2()

 

你可能感兴趣的:(数据处理,深度学习)