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

我有一个具有透视失真的池表的image,在手动 Select 四个角(按左上角、右上角、左下角、右下角的顺序)时,cv2.getPerspectiveTransform计算将池表的角转换为显示窗口的角所需的3x3矩阵.然后,我应用cv2.warpPerspective将池表图像与计算出的矩阵不失真.

我想使用此矩阵将各个点从扭曲的池表图像转换为未扭曲的池表图像.当我试图通过将3x3变换矩阵乘以角点坐标(按照链接文档写为(x,y,1))来用变换矩阵变换扭曲池表的相同手动 Select 角点时,变换后的角点与所显示窗口的角点不匹配(如下所示).也就是说,红点应该在图像的角落,但不是.

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.透视变换到变换点.

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

Python相关问答推荐

Django:如何将一个模型的唯一实例创建为另一个模型中的字段

为什么图像结果翻转了90度?

如何输入提示抽象方法属性并让mypy高兴?

在Python中是否可以输入使用任意大小参数列表的第一个元素的函数

有什么方法可以修复奇怪的y轴Python matplotlib图吗?

使用Beautiful Soup获取第二个srcset属性

将DF中的名称与另一DF拆分并匹配并返回匹配的公司

Pydantic 2.7.0模型接受字符串日期时间或无

我在使用fill_between()将最大和最小带应用到我的图表中时遇到问题

追溯(最近最后一次调用):文件C:\Users\Diplom/PycharmProject\Yolo01\Roboflow-4.py,第4行,在模块导入roboflow中

如何根据参数推断对象的返回类型?

在Google Colab中设置Llama-2出现问题-加载判断点碎片时Cell-run失败

将输入管道传输到正在运行的Python脚本中

从groupby执行计算后创建新的子框架

组/群集按字符串中的子字符串或子字符串中的字符串轮询数据框

在vscode上使用Python虚拟环境时((env))

多指标不同顺序串联大Pandas 模型

改进大型数据集的框架性能

用渐近模计算含符号的矩阵乘法

为什么numpy. vectorize调用vectorized函数的次数比vector中的元素要多?