Rectangular Padding代码实现

统一定义:

  • size: (width, height)
  • shape: (rows, cols, channels)

检测是否符合grid size的倍数要求

gs = int(max(model.stride))  # grid size (max stride)
def check_img_size(img_size: list, gs):
    new_size = img_size.copy()  # [width, height]
    for i in range(len(img_size)):
        new_size[i] = math.ceil(img_size[i] / gs) * gs
    if new_size != img_size:
        print(f'WARNING: --img-size {img_size} must be multiple of max stride {gs}, updating to {new_size}')
    return new_size

Rectangular Padding 矩形填充

def letterbox(img, new_size=(640, 640), color=(114, 114, 114), scaleup=True):
    # Resize image to a 32-pixel-multiple rectangle https://github.com/ultralytics/yolov3/issues/232
    size = [img.shape[1], img.shape[0]]  # [width, height]
    if isinstance(new_size, int):
        new_size = (new_size, new_size)

    # Scale ratio (new / old)
    ratio = min(new_size[0] / size[0], new_size[1] / size[1])

    # Compute padding
    new_size_unpad = int(round(size[0] * ratio)), int(round(size[1] * ratio))
    dw, dh = new_size[0] - new_size_unpad[0], new_size[1] - new_size_unpad[1]  # wh padding
    dw, dh = np.mod(dw, 64), np.mod(dh, 64)  # wh padding
    dw /= 2  # divide padding into 2 sides
    dh /= 2

    if size[0] != new_size_unpad[0]:  # resize
        img = cv2.resize(img, new_size_unpad, interpolation=cv2.INTER_LINEAR)
    top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))
    left, right = int(round(dw - 0.1)), int(round(dw + 0.1))
    img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)  # add border
    return img

坐标恢复 rescale_coords

def rescale_coords(coords: torch.Tensor, init_size, ratio, dw, dh):
    coords[:, [0, 2]] -= dw  # x padding
    coords[:, [1, 3]] -= dh  # y padding
    coords[:, :4] /= ratio
    # Clip bounding xyxy bounding boxes to image shape (height, width)
    coords[:, 0].clamp_(0, init_size[0])  # x1
    coords[:, 1].clamp_(0, init_size[1])  # y1
    coords[:, 2].clamp_(0, init_size[0])  # x2
    coords[:, 3].clamp_(0, init_size[1])  # y2
    return coords

测试代码

def main():
    img_size = [900, 550]
    img = np.ones([img_size[1], img_size[0], 3], dtype="uint8") * 255
    m, n, _ = img.shape
    cx, cy, r = n // 2, m // 2, 80
    cv2.circle(img, (cx, cy), r, (80, 180, 80), -1)
    cv2.imshow("img", img)

    new_size = check_img_size(img_size, 32)
    dst, ratio, (dw, dh) = letterbox(img, new_size)
    cv2.imshow("dst", dst)
    
    bbox = cv2.selectROI("dst", dst)
    
    x1, y1, x2, y2 = bbox[0], bbox[1], bbox[0] + bbox[2], bbox[1] + bbox[3]
    bboxes = torch.Tensor([[x1, y1, x2, y2]])
    bboxes = rescale_coords(bboxes, img_size, ratio, dw, dh)

    x1, y1, x2, y2 = bboxes[0]
    cv2.rectangle(img, (x1, y1), (x2, y2), (80, 180, 80), 3)
    cv2.imshow("dst", img)

    cv2.waitKey(0)
    cv2.destroyAllWindows()


if __name__ == '__main__':
    main()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值