Opencv使用数据增强中斜矩形裁剪成正矩形的方法

发布于:2024-03-21 ⋅ 阅读:(73) ⋅ 点赞:(0)

先旋转大图再进行裁剪(推荐)

def rotate_bound(image, angle, center):
    '''
    image: 原始图像
    angle: 斜矩形的角度
    center: 斜矩形的中心坐标
    '''
   
    (h, w) = image.shape[:2]
    (cX, cY) = center
  
    M = cv2.getRotationMatrix2D((cX, cY), angle, 1.0)
    cos = np.abs(M[0, 0])
    sin = np.abs(M[0, 1])
  
    nW = int((h * sin) + (w * cos))
    nH = int((h * cos) + (w * sin))
  
    M[0, 2] += (nW / 2) - cX
    M[1, 2] += (nH / 2) - cY

    pts = np.float32(center).reshape([-1, 2])  
    pts = np.hstack([pts, np.ones([len(pts), 1])]).T
    target_point = np.dot(M, pts).astype(int)

    '''
    返回:
    1.斜矩形旋转后的中心坐标
    2.原始图像旋转后的新图像
    '''
  
    return tuple(target_point[:,0]), cv2.warpAffine(image, M, (nW, nH), borderValue=(255,255,255))
'''
im0: 原始包含斜矩形的图像
angle: 斜矩形框的弧度
(cx,cy): 斜矩形框的中心坐标
x: 斜矩形框的宽
y: 斜矩形框的高
'''
rect = ((cx,cy),(x,y),angle)
(n_cX, n_cY), whole_img = rotate_bound(im0.copy(), angle*180/math.pi, (cx,cy))
crop_img = whole_img.copy()[int(n_cY-y*0.7):int(n_cY+y*0.7), int(n_cX-x*0.7):int(n_cX+x*0.7)]
'''
(n_cX, n_cY): 斜矩形框旋转后的中心坐标
crop_img: 裁剪后的图像,正常是-0.5到0.5,可以设置0.7,调大斜矩形范围
'''

先裁剪目标小图,再进行旋转(会丢失部分信息,或者框的不准)

def rotate_bound(image, angle, center):
    '''
    image: 原始图像
    angle: 斜矩形的角度
    center: 斜矩形的中心坐标
    '''
   
    (h, w) = image.shape[:2]
    (cX, cY) = center
  
    M = cv2.getRotationMatrix2D((cX, cY), angle, 1.0)
    cos = np.abs(M[0, 0])
    sin = np.abs(M[0, 1])
  
    nW = int((h * sin) + (w * cos))
    nH = int((h * cos) + (w * sin))

    pts = np.float32(center).reshape([-1, 2])  
    pts = np.hstack([pts, np.ones([len(pts), 1])]).T
    target_point = np.dot(M, pts).astype(int)

    '''
    返回:
    1.斜矩形旋转后的中心坐标
    2.原始图像旋转后的新图像
    '''
  
    return tuple(target_point[:,0]), cv2.warpAffine(image, M, (nW, nH))
rect = ((cx,cy),(x,y),angle)
box = cv2.boxPoints(rect).astype(np.int)
x, y, w, h = cv2.boundingRect(box)  # 最大外接矩形(左上点坐标,宽与高)
cropImg = im0[int(y):int(y+h), int(x):int(x+w)]
_, cropImg = rotate_bound(cropImg.copy(), angle*180/math.pi, (int(w/2), int(h/2)))
本文含有隐藏内容,请 开通VIP 后查看