如何在二维图像的一个点旋转后找到平移值?
How to find the translation values after a rotate about a point for a 2D image?
我在旋转图像后无法获得正确的翻译值。到目前为止,我的代码使用基本三角学计算给定旋转的边界框,然后将平移应用于旋转矩阵。然而,我遇到的问题是我的翻译似乎总是超出 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 - 90° - 注意顶部的 1px 边框
coffee.png - 180° - 注意顶部和左侧的 1px 边框
我对数学不是很感兴趣,但我猜测这是由于我们处理浮点数时的一些舍入问题引起的。
我想知道其他人使用什么方法,请问关于图像中心点旋转和平移图像的最简单和最高效的方法是什么?
谢谢。
编辑
根据@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
我仍然很高兴看到人们使用其他方法来执行旋转和平移! :)
我猜你的图像中心是错误的。例如,一张 4x4 的图像,其中包含第 0、1、2 和 3 列。然后您的中心计算为 4 / 2 = 2。但第 1 列和第 2 列之间应该为 1.5。
所以你最好使用 (width - 1) / 2.0 和 (height - 1) / 2.0。
我在旋转图像后无法获得正确的翻译值。到目前为止,我的代码使用基本三角学计算给定旋转的边界框,然后将平移应用于旋转矩阵。然而,我遇到的问题是我的翻译似乎总是超出 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 - 90° - 注意顶部的 1px 边框
coffee.png - 180° - 注意顶部和左侧的 1px 边框
我对数学不是很感兴趣,但我猜测这是由于我们处理浮点数时的一些舍入问题引起的。 我想知道其他人使用什么方法,请问关于图像中心点旋转和平移图像的最简单和最高效的方法是什么?
谢谢。
编辑
根据@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
我仍然很高兴看到人们使用其他方法来执行旋转和平移! :)
我猜你的图像中心是错误的。例如,一张 4x4 的图像,其中包含第 0、1、2 和 3 列。然后您的中心计算为 4 / 2 = 2。但第 1 列和第 2 列之间应该为 1.5。
所以你最好使用 (width - 1) / 2.0 和 (height - 1) / 2.0。