如何在围绕2D图像的点旋转后找到平移值?

时间:2015-11-25 11:34:04

标签: python opencv rotation opencv3.0 affinetransform

旋转图像后,我在获取正确的翻译值时遇到问题。到目前为止,我的代码使用基本三角函数计算给定旋转的边界框,然后将平移应用于旋转矩阵。然而,我遇到的问题是我的翻译似乎总是1像素,我的意思是我在旋转图像的顶部或侧面得到一个1像素的黑色边框。

这是我的代码:

def rotate_image(mat, angle):
    height, width = mat.shape[:2]
    image_center = (width / 2.0, height / 2.0)
    rotation_mat = cv2.getRotationMatrix2D(image_center, angle, 1.0)

    # Get Bounding Box
    radians = math.radians(angle)
    sin = abs(math.sin(radians))
    cos = abs(math.cos(radians))
    bound_w = (width * cos) + (height * sin)
    bound_h = (width * sin) + (height * cos)

    # Set Translation
    rotation_mat[0, 2] += (bound_w / 2.0) - image_center[0]
    rotation_mat[1, 2] += (bound_h / 2.0) - image_center[1]

    rotated_mat = cv2.warpAffine(mat, rotation_mat, (int(bound_w), int(bound_h)))
    return rotated_mat

以下是供参考的原始图像和使用该代码的图像的一些示例:

coffee.png - 原创 coffee.png – Original

coffee.png - 90° - 注意顶部的1px边框 coffee.png - 90°

coffee.png - 180° - 注意顶部和左侧的1px边框 coffee.png - 1°

我的数学并不是那么热,但我猜测这是由于我们处理浮点数而导致的一些舍入问题。 我想知道其他人使用什么方法,旋转和翻译图像的最简单,最高效的方法是什么?

谢谢。

编辑

根据@Falko的回答,我没有使用从零开始的计算。我更正后的代码如下:

def rotate_image(mat, angle):
    height, width = mat.shape[:2]
    image_center = ((width - 1) / 2.0, (height - 1) / 2.0)
    rotation_mat = cv2.getRotationMatrix2D(image_center, angle, 1.0)

    # Get Bounding Box
    radians = math.radians(angle)
    sin = abs(math.sin(radians))
    cos = abs(math.cos(radians))
    bound_w = (width * cos) + (height * sin)
    bound_h = (width * sin) + (height * cos)

    # Set Translation
    rotation_mat[0, 2] += ((bound_w - 1) / 2.0 - image_center[0])
    rotation_mat[1, 2] += ((bound_h - 1) / 2.0 - image_center[1])

    rotated_mat = cv2.warpAffine(mat, rotation_mat, (int(bound_w), int(bound_h)))
    return rotated_mat

我仍然很欣赏人们用来执行旋转和翻译的替代方法! :)

1 个答案:

答案 0 :(得分:2)

我猜你的影像中心错了。例如,使用列0,1,2和3的4x4图像。然后您的中心计算为4/2 = 2.但是在第1列和第2列之间它应该是1.5。

所以你最好使用(width-1)/ 2.0和(height-1)/ 2.0。