旋转矩形透视变换并裁剪
# -*- coding: utf-8 -*- # ---------------------------- # ! Copyright(C) 2022 # All right reserved. # 文件名称:xxx.py # 摘 要:xxx # 当前版本:1.0 # 作 者:刘恩甫 # 完成日期:2022-x-x # ----------------------------- import json import os import cv2 import numpy as np import math from math import fabs,sin,cos,radians,acos def rotate(img,pt1, pt2, pt3, pt4): withRect = math.sqrt((pt4[0] - pt1[0]) ** 2 + (pt4[1] - pt1[1]) ** 2) # 矩形框的宽度 heightRect = math.sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) **2) angle = acos((pt4[0] - pt1[0]) / withRect) * (180 / math.pi) # 矩形框旋转角度 if pt4[1]>pt1[1]: pass else: angle=-angle height,width = img.shape[0], img.shape[1] rotateMat = cv2.getRotationMatrix2D((width / 2, height / 2), angle, 1) # 按angle角度旋转图像 heightNew = int(width * fabs(sin(radians(angle))) + height * fabs(cos(radians(angle)))) widthNew = int(height * fabs(sin(radians(angle))) + width * fabs(cos(radians(angle)))) rotateMat[0, 2] += (widthNew - width) / 2 rotateMat[1, 2] += (heightNew - height) / 2 imgRotation = cv2.warpAffine(img, rotateMat, (widthNew, heightNew), borderValue=(255, 255, 255)) # 旋转后图像的四点坐标 [[pt1[0]], [pt1[1]]] = np.dot(rotateMat, np.array([[pt1[0]], [pt1[1]], [1]])) [[pt3[0]], [pt3[1]]] = np.dot(rotateMat, np.array([[pt3[0]], [pt3[1]], [1]])) [[pt2[0]], [pt2[1]]] = np.dot(rotateMat, np.array([[pt2[0]], [pt2[1]], [1]])) [[pt4[0]], [pt4[1]]] = np.dot(rotateMat, np.array([[pt4[0]], [pt4[1]], [1]])) # 处理反转的情况 if pt2[1]>pt4[1]: pt2[1],pt4[1]=pt4[1],pt2[1] if pt1[0]>pt3[0]: pt1[0],pt3[0]=pt3[0],pt1[0] imgOut = imgRotation[int(pt2[1]):int(pt4[1]), int(pt1[0]):int(pt3[0])] #做长宽比较 crop_w,crop_h,crop_c=imgOut.shape if crop_w>crop_h: imgOut=np.rot90(imgOut,k=3) rotated_img=cv2.resize(imgRotation,dsize=None,fx=.25,fy=.25) crop_img=cv2.resize(imgOut,dsize=None,fx=.25,fy=.25) cv2.imshow('rotated img',rotated_img) cv2.imshow("cropped img",crop_img) # 裁减得到的旋转矩形框 return imgRotation if __name__ == '__main__': base_path=r'D:\liu_projects\package_maskrcnn_20220628\truck_warp_affine\\' for path in os.listdir(base_path): name,ext=os.path.splitext(path) if ext=='.json': img=cv2.imread(base_path+name+'.jpg') json_data=json.load(open(base_path + name+'.json', 'r', encoding='utf-8')) for j in range(len(json_data['shapes'])): label = json_data['shapes'][j]['label'] point_array = np.array(json_data['shapes'][j]['points']).astype(np.int) rotatedRect = cv2.minAreaRect(point_array) # 计算最小外接矩形 box = cv2.boxPoints(rotatedRect) #计算矩形的坐标 box = np.int0(box) img_copy=img.copy() #画轮廓 for k in range(len(point_array)-1): cv2.line(img_copy, (point_array[k][0], point_array[k][1]), (point_array[k + 1][0], point_array[k + 1][1]), (0,0,255), 5) #画最小外接矩形 for k in range(len(box)-1): cv2.line(img_copy,(box[k][0],box[k][1]),(box[k+1][0],box[k+1][1]),(255,0,0),5) cv2.line(img_copy,(box[-1][0],box[-1][1]),(box[0][0],box[0][1]),(255,0,0),5) imgRotation=rotate(img, box[0], box[1], box[2], box[3]) resized_img=cv2.resize(img_copy,dsize=None,fx=.25,fy=.25) cv2.imshow('resized_img',resized_img) cv2.waitKey(0)