最近需要实现一个在一张大图上给定一个带方向的点,以这个点为中心,以方向为角度裁剪出一个矩形区域。在网上查到很多方法都是先对大图像进行旋转,再从中切片取出目标区域。不失为一个好办法,但是我要处理的图像太大(10000*10000),先旋转再切片太浪费时间(测试大概需要1.6s)。恰好在一篇论文的代码里找到了实现该功能的代码,在这里给出来。
代码
import numpy as np
import matplotlib.pyplot as plt
import cv2
#定义了一个2维旋转矩阵
def RotationMatrix2d(theta):
return np.array([[np.cos(theta),-np.sin(theta)],[np.sin(theta),np.cos(theta)]])
#输入分别是 大图像,点坐标(x,y),点的朝向,要裁剪区域矩形的边长,生成区域的边长,缩放大小(基本上设置为1即可)
def cropRectangularSectionFromImage(image,x,y,theta,sourceDim,targetDim,scale=1.0):
dst_points = np.array([[0,0],[targetDim,0],[targetDim,targetDim],[0,targetDim]])
#src_points这里除2看似有负数是为了方便能直接加上中心点坐标进行平移
src_points = np.array([[-sourceDim/(2*scale),-sourceDim/(2*scale)],[sourceDim/(2*scale),-sourceDim/(2*scale)],[sourceDim/(2*scale),sourceDim/(2*scale)],[-sourceDim/(2*scale),sourceDim/(2*scale)]])
R = RotationMatrix2d(theta)
# rotate source points
src_points = np.matmul(R,src_points.T).T
# translate source points
#至此要裁剪的区域就已经表示出来了
src_points = src_points + np.array([[x,y]])
#计算单应矩阵再结合opencv就能很快的取出来目标区域了
h, _ = cv2.findHomography(src_points,dst_points)
cropped = cv2.warpPerspective(image,h,(targetDim,targetDim))
return cropped
如果取的区域是个梯形或者一般四边形那就改soucepoint的定义就行了。
也可以参考这篇 他给出的第二种方法和上述方法原理是一致的。
link