如何在python中使用opencv拉直图像的旋转矩形区域?

2024-05-17 06:25:28 发布

您现在位置:Python中文网/ 问答频道 /正文

下面的图片会告诉你我想要什么。

我有图像中矩形的信息,宽度,高度,中心点和旋转度。现在,我想写一个脚本,把它们剪下来保存为图像,但要把它们弄直。我想从图像内部显示的矩形转到外部显示的矩形。

我正在使用OpenCV python,请告诉我实现这一点的方法。

显示一些很难找到的OpenCV Python示例代码。

Example Image


Tags: 方法代码图像脚本信息示例宽度高度
3条回答

我在这里有错误的补偿问题,在类似的问题张贴解决方案。 所以我做了数学计算,得出了以下有效的解决方案:

def subimage(self,image, center, theta, width, height):
    theta *= 3.14159 / 180 # convert to rad

    v_x = (cos(theta), sin(theta))
    v_y = (-sin(theta), cos(theta))
    s_x = center[0] - v_x[0] * ((width-1) / 2) - v_y[0] * ((height-1) / 2)
    s_y = center[1] - v_x[1] * ((width-1) / 2) - v_y[1] * ((height-1) / 2)

    mapping = np.array([[v_x[0],v_y[0], s_x],
                        [v_x[1],v_y[1], s_y]])

    return cv2.warpAffine(image,mapping,(width, height),flags=cv2.WARP_INVERSE_MAP,borderMode=cv2.BORDER_REPLICATE)

作为参考,这里有一张图片解释了其背后的数学原理:

请注意

w_dst = width-1
h_dst = height-1

这是因为最后一个坐标的值是width-1,而不是width;或者height

如果有关于数学的问题,把它们当作评论来问,我会尽力回答。

可以使用^{}函数围绕定义的中心点旋转图像。可以使用^{}(其中theta中)生成合适的旋转矩阵。

Start ImageAfter finding the desired rectangle

然后可以使用Numpy slicing剪切图像。

Rotated ImageResult

import cv2
import numpy as np

def subimage(image, center, theta, width, height):

   ''' 
   Rotates OpenCV image around center with angle theta (in deg)
   then crops the image according to width and height.
   '''

   # Uncomment for theta in radians
   #theta *= 180/np.pi

   shape = ( image.shape[1], image.shape[0] ) # cv2.warpAffine expects shape in (length, height)

   matrix = cv2.getRotationMatrix2D( center=center, angle=theta, scale=1 )
   image = cv2.warpAffine( src=image, M=matrix, dsize=shape )

   x = int( center[0] - width/2  )
   y = int( center[1] - height/2 )

   image = image[ y:y+height, x:x+width ]

   return image

记住dsize输出图像的形状。如果面片/角度足够大,如果使用原始形状(为了简单起见)执行上述操作,则边缘将被截断(比较上面的图像)。在这种情况下,可以将缩放因子引入到shape(放大输出图像)和切片的参考点(这里是center)。

上述功能可以使用如下:

image = cv2.imread('owl.jpg')
image = subimage(image, center=(110, 125), theta=30, width=100, height=200)
cv2.imwrite('patch.jpg', image)

openCV版本3.4.0的类似配方。

from cv2 import cv
import numpy as np

def getSubImage(rect, src):
    # Get center, size, and angle from rect
    center, size, theta = rect
    # Convert to int 
    center, size = tuple(map(int, center)), tuple(map(int, size))
    # Get rotation matrix for rectangle
    M = cv2.getRotationMatrix2D( center, theta, 1)
    # Perform rotation on src image
    dst = cv2.warpAffine(src, M, src.shape[:2])
    out = cv2.getRectSubPix(dst, size, center)
    return out

img = cv2.imread('img.jpg')
# Find some contours
thresh2, contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# Get rotated bounding box
rect = cv2.minAreaRect(contours[0])
# Extract subregion
out = getSubImage(rect, img)
# Save image
cv2.imwrite('out.jpg', out)

相关问题 更多 >