python - cv2.getPerspectiveTransform 中的矩阵未正确转换点

标签 python opencv image-processing matrix

function cv2.getPerspectiveTransform 根据四对对应点计算透视变换的 3x3 矩阵。

我有一个image具有透视畸变的台球 table ,在手动选择四个角(按左上角、右上角、左下角、右下角的顺序)时,cv2.getPerspectiveTransform 计算变换所需的 3x3 矩阵台球 table 的角到显示窗口的角。然后,我应用 cv2.warpPerspective 使用计算出的矩阵来消除台球 table 图像的扭曲。

我想使用这个矩阵将各个点从扭曲的台球 table 图像转换为未扭曲的台球 table 图像。当我尝试通过将 3x3 变换矩阵与角坐标(根据链接文档写为 (x, y, 1))相乘来使用变换矩阵来变换扭曲台球 table 的相同手动选择的角时,变换后的角点与预期的显示窗口的角不匹配(如下所示)。也就是说,红点应该位于图像的角落,但事实并非如此。

Failed Corner Transformation

有人可以解释为什么变换后的角点与显示窗口的角点不匹配吗?

下面附上我的代码:

import cv2
import numpy as np


def mouse_position(event, mouse_x, mouse_y, flags, param):
    global corners
    if event == cv2.EVENT_LBUTTONDOWN:
        print(f"Corner #{len(corners) + 1}: {(mouse_x, mouse_y)}")
        corners.append((mouse_x, mouse_y))


corners = []
img = cv2.imread("Assets/Setup.jpg")
cv2.namedWindow("Select Corners of Pool Table")
cv2.setMouseCallback("Select Corners of Pool Table", mouse_position)
while len(corners) < 4:
    cv2.imshow("Select Corners of Pool Table", img)
    if cv2.waitKey(1) != -1:
        print("Exiting program.")
        cv2.destroyAllWindows()
        exit(0)
cv2.destroyAllWindows()
corners = np.array(corners, dtype="float32")
height, width = img.shape[:2]
transform_matrix = cv2.getPerspectiveTransform(corners, np.array([(0, 0), (width, 0), (0, height), (width, height)],
                                                                 dtype="float32"))
undistorted_image = cv2.warpPerspective(img, transform_matrix, (width, height))
transformed_corners = (transform_matrix @ np.hstack((corners, np.ones((corners.shape[0], 1)))).T).T.astype(int)
for corner in transformed_corners:
    cv2.circle(undistorted_image, (corner[0], corner[1]), 30, (0, 0, 255), -1)
cv2.imshow("Frame", undistorted_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

最佳答案

您可以使用 cv2.perspectiveTransform 来变换点。

如果您想手动执行此操作,请将 (x,y,1) 与 3x3 变换矩阵相乘,请确保将结果除以它的 z 值,因此结果将是 (x',y',1 )并且是齐次点表示。

关于python - cv2.getPerspectiveTransform 中的矩阵未正确转换点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72386746/

相关文章:

matlab - 如何使用matlab平滑图片的边缘

python - 使用 Python 和 imaplib 处理编码消息

opencv - 如何跟踪足球的位置?

python - python中imread的相对路径

python - 如何使用Python检测视频OpenCV中的对象?

matlab - 如何消除图像中不需要的小区域

python - OpenCV掩码错误错误:(-215:声明失败)(mtype == CV_8U || mtype == CV_8S)&& _mask.sameSize(* psrc1)在函数'cv::binary_op中

python - matplotlib 只能更新最新的点到图中吗?

python - 在 NumPy 中创建随机 float 和 float64 数组

python - 从 POST 请求获取对神经网络 web.py 包装器的响应