opencv 图片旋转截断问题解决方法

在使用opencv对图片进行旋转缩放的过程中会出现原图截断的问题,这个问题其实可以直接通过设置参数解决。

一般使用opencv对图片进行旋转缩放的流程是首先调用“getRotationMatrix2D”获得仿射变换矩阵,然后调用“warpAffine”对图片进行变换。其中“warpAffine”有一个参数可以用来控制变换后的图片大小,但变换后的图片大小如何获得呢?

一个可行的方法是我们知道图片的尺寸,对这个尺寸进行相同的仿射变换,然后就可以得到变换后的图片尺寸。代码如下:

    origin_corner_position = [[0, 0], [0, image_height], [image_width, 0], [image_height, image_width]]

    mat = cv2.getRotationMatrix2D((image_height/2, image_width/2), 30, 1.2)

    for index, point in enumerate(origin_corner_position):
        origin_corner_position[index] = np.matmul(mat, np.array([point[0], point[1], 1]).T)

    boundingBox = cv2.boundingRect(np.array(origin_corner_position, dtype=np.int32))

如此就可以获得变换后的图片尺寸,但仅知道变换后的图片尺寸还不够,因为图片旋转缩放后,座标系原点也发生改变,因此还需要进行如下操作对座标系原点进行平移:

    mat[0][2] += (boundingBox[2] - image_width)/2
    mat[1][2] += (boundingBox[3] - image_height) / 2

仿射变换矩阵中mat[0][2],mat[1][2]两个量控制平移参数。

    new_image = cv2.warpAffine(image, mat, (boundingBox[2], boundingBox[3]))

此时再调用warpAffine就可以获得经过变换且图片不会截断的新图片。

对于这个问题其实还有一个解决方法,直接把原图片贴到一张新大小的全0背景图片上去,然后对新图片进行旋转缩放,要注意的一点是新图片的旋转中心发生了改变,变为新图片的中心。代码如下:

    origin_corner_position = [[0, 0], [0, image_height], [image_width, 0], [image_height, image_width]]

    mat = cv2.getRotationMatrix2D((256, 256), 30, 1.2)

    for index, point in enumerate(origin_corner_position):
        origin_corner_position[index] = np.matmul(mat, np.array([point[0], point[1], 1]).T)

    boundingBox = cv2.boundingRect(np.array(origin_corner_position, dtype=np.int32))

    background = np.zeros((boundingBox[2], boundingBox[3]), dtype=np.uint8)
    startX = int((boundingBox[2] - image_width)/2)
    startY = int((boundingBox[3] - image_height) / 2)

    background[startX: startX + image_width, startY: startY + image_height] = image

    mat = cv2.getRotationMatrix2D((boundingBox[2]/2, boundingBox[3]/2), 30, 1.2)
    new_image = cv2.warpAffine(background, mat, (boundingBox[2], boundingBox[3]))

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章