旋转矩形透视变换并裁剪

# -*- 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)

 

posted @ 2022-06-30 16:45  刘恩福  阅读(103)  评论(0编辑  收藏  举报