当前位置: 首页 > 知识库问答 >
问题:

如何在蟒蛇中使用OpenCV拉直图像的旋转矩形区域?

唐腾
2023-03-14

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

我有图像中矩形的信息(宽度,高度,中心点和旋转度)。现在,我想写一个脚本来剪切它们并将它们保存为图像,但也要将它们拉直。就像这样,我想从图像内部显示的矩形转到外部显示的矩形。

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

请展示一些代码,因为OpenCVPython的例子很难找到。

共有3个答案

云新知
2023-03-14

仅当矩形的内容在旋转后位于旋转的图像中并且在其他情况下将严重失败时,其他方法才有效。如果某些部件丢失了怎么办?请参阅下面的示例:

如果要使用上述方法裁剪旋转的矩形文本区域,

import cv2
import numpy as np


def main():
    img = cv2.imread("big_vertical_text.jpg")
    cnt = np.array([
            [[64, 49]],
            [[122, 11]],
            [[391, 326]],
            [[308, 373]]
        ])
    print("shape of cnt: {}".format(cnt.shape))
    rect = cv2.minAreaRect(cnt)
    print("rect: {}".format(rect))

    box = cv2.boxPoints(rect)
    box = np.int0(box)

    print("bounding box: {}".format(box))
    cv2.drawContours(img, [box], 0, (0, 0, 255), 2)

    img_crop, img_rot = crop_rect(img, rect)

    print("size of original img: {}".format(img.shape))
    print("size of rotated img: {}".format(img_rot.shape))
    print("size of cropped img: {}".format(img_crop.shape))

    new_size = (int(img_rot.shape[1]/2), int(img_rot.shape[0]/2))
    img_rot_resized = cv2.resize(img_rot, new_size)
    new_size = (int(img.shape[1]/2)), int(img.shape[0]/2)
    img_resized = cv2.resize(img, new_size)

    cv2.imshow("original contour", img_resized)
    cv2.imshow("rotated image", img_rot_resized)
    cv2.imshow("cropped_box", img_crop)

    # cv2.imwrite("crop_img1.jpg", img_crop)
    cv2.waitKey(0)


def crop_rect(img, rect):
    # get the parameter of the small rectangle
    center = rect[0]
    size = rect[1]
    angle = rect[2]
    center, size = tuple(map(int, center)), tuple(map(int, size))

    # get row and col num in img
    height, width = img.shape[0], img.shape[1]
    print("width: {}, height: {}".format(width, height))

    M = cv2.getRotationMatrix2D(center, angle, 1)
    img_rot = cv2.warpAffine(img, M, (width, height))

    img_crop = cv2.getRectSubPix(img_rot, size, center)

    return img_crop, img_rot


if __name__ == "__main__":
    main()

这是你将得到的:

显然,有些零件被切掉了!为什么不直接扭曲旋转的矩形,因为我们可以用<code>cv获得它的四个角点。boxPoints()方法?

import cv2
import numpy as np


def main():
    img = cv2.imread("big_vertical_text.jpg")
    cnt = np.array([
            [[64, 49]],
            [[122, 11]],
            [[391, 326]],
            [[308, 373]]
        ])
    print("shape of cnt: {}".format(cnt.shape))
    rect = cv2.minAreaRect(cnt)
    print("rect: {}".format(rect))

    box = cv2.boxPoints(rect)
    box = np.int0(box)
    width = int(rect[1][0])
    height = int(rect[1][1])

    src_pts = box.astype("float32")
    dst_pts = np.array([[0, height-1],
                        [0, 0],
                        [width-1, 0],
                        [width-1, height-1]], dtype="float32")
    M = cv2.getPerspectiveTransform(src_pts, dst_pts)
    warped = cv2.warpPerspective(img, M, (width, height))

现在裁剪的图像变成

好多了,不是吗?如果仔细检查,您会注意到裁剪后的图像中有一些黑色区域。这是因为检测到的矩形的一小部分超出了图像的边界。为了解决这个问题,您可以稍微填充图像并在那之后进行裁剪。这个答案中有一个例子。

现在,我们比较两种从图像中裁剪旋转矩形的方法。这种方法不需要旋转图像,可以用更少的代码更优雅地处理这个问题。

哈和惬
2023-03-14

我在这里和类似问题中使用解决方案时遇到了错误偏移的问题。

所以我做了数学计算,并提出了以下有效的解决方案:

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

这是因为最后一个坐标的值是< code>width-1,而不是< code>width或< code>height。

戈华茂
2023-03-14

您可以使用warpAffine函数围绕定义的中心点旋转图像。可以使用getRotationMatrix2D生成合适的旋转矩阵(其中theta以度为单位)。

然后,您可以使用Numpy切片来剪切图像。

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是输出图像的形状。如果补丁/角度足够大,如果使用原始形状(为了简单起见),边缘会被切断(比较上面的图像)。在这种情况下,您可以为形状(放大输出图像)和切片参考点(这里是center)引入缩放因子。

以上功能可以使用如下:

image = cv2.imread('owl.jpg')
image = subimage(image, center=(110, 125), theta=30, width=100, height=200)
cv2.imwrite('patch.jpg', image)
 类似资料:
  • 本文向大家介绍openCV提取图像中的矩形区域,包括了openCV提取图像中的矩形区域的使用技巧和注意事项,需要的朋友参考一下 改编自详解利用OpenCV提取图像中的矩形区域(PPT屏幕等) 原文是c++版,我改成了python版,供大家参考学习。 主要思想:边缘检测—》轮廓检测—》找出最大的面积的轮廓—》找出顶点—》投影变换 运行效果 用到的图片 以上就是本文的全部内容,希望对大家的学习有所帮助

  • 在pygame中,我对我的程序中的所有矩形使用。我希望能够将这些矩形旋转到任何角度。我已经看到了以下旋转IMAGES的代码,但我的问题是RECTANGLES。 但是我正在使用矩形,我没有可以旋转的图像或“表面”。当我尝试旋转矩形时 这就给出了 我的问题是,如何在pygame中旋转a并显示矩形<code>(x,y,w,h),而不是图像。 这是“潜在重复”的链接帖子不是重复的。一个答案解释了旋转矩形的

  • 本文向大家介绍使用OpenCV检测图像中的矩形,包括了使用OpenCV检测图像中的矩形的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了OpenCV检测图像中矩形的具体代码,供大家参考,具体内容如下 前言 1.OpenCV没有内置的矩形检测的函数,如果想检测矩形,要自己去实现。 2.我这里使用的OpenCV版本是3.30. 矩形检测 1.得到原始图像之后,代码处理的步骤是: (1)滤波

  • 此外,我已经把我的矩形在锚窗,如果这是重要的知道。

  • 我是python的新手,在处理矩阵时遇到了一个问题。 我有一个矩阵,比方说 现在,我想让矩阵中的所有元素都等于零,除了在矩阵中重复最多次的元素。(在这种情况下,它是3)。 所以预期的结果是, 如果有人能帮我做这个的python代码,那真的很有帮助。

  • 问题内容: 我需要创建围绕其中心旋转的矩形(因此它们不必平行于坐标系的轴)。因此,基本上每个矩形都可以由 center-X , center-Y , width , height 和 angle定义 。然后,我要做的是对这些矩形中是否包含某些点进行计算(因此不会涉及任何绘图)。我想我不能使用该类,因为这些矩形将始终与坐标系的x和y轴平行。是通过编写自己的矩形类来获得此功能的唯一方法,还是可以使用任