通过透视变换获取对应点的像素位置

56 阅读2分钟

在图像处理中,透视变换是一种常见的图像几何变换,它可以将图像中的一个平面映射到另一个平面上。在透视变换中,图像中的点经过变换后,其像素位置也会发生变化。因此,我们经常需要知道透视变换后,图像中某个点的像素位置。

  1. 解决方案

我们可以通过直接使用 OpenCV 中的 cv2.perspectiveTransform 函数来计算透视变换后,图像中某个点的像素位置。该函数接收两个参数,第一个参数是需要进行透视变换的点,第二个参数是透视变换矩阵。

dst_pt = cv2.perspectiveTransform(pt, M)

其中,dst_pt 是经过透视变换后的点,pt 是需要进行透视变换的点,M 是透视变换矩阵。

在透视变换后,图像中某个点的像素位置可能会发生变化,但是该点的相对位置不会发生变化。因此,我们也可以根据透视变换前后的图像中该点的相对位置来计算出透视变换后,该点的像素位置。

例如,如果我们知道透视变换前,该点位于图像的中心位置,那么透视变换后,该点也应该位于图像的中心位置。因此,我们可以通过计算透视变换后,图像的中心位置来得到透视变换后,该点的像素位置。

center_pt_warpped = np.array([[[warpped_img.shape[1] / 2, warpped_img.shape[0] / 2]]], dtype=np.float32)
dst_pt_center = cv2.perspectiveTransform(center_pt_warpped, M)
dst_pt_center = dst_pt_center.astype(int)
dst_pt_center = tuple(dst_pt_center[0,0,].tolist())

其中,center_pt_warpped 是透视变换前,图像中心点的像素位置,dst_pt_center 是透视变换后,图像中心点的像素位置。

下面是一个示例代码,展示了如何计算透视变换后,图像中某个点的像素位置:

import cv2
import numpy as np

original_img = cv2.imread('1.jpg')
# one point(400,560) on the original image
cv2.circle(original_img, (400,560), 7, (0,255,255), -1)
original_points = np.float32([(0,560), (0,450), (795,568), (795,748)])
destination_points = np.float32([(0,400), (0,0), (600,0), (600,400)])
# transformation matrix
M = cv2.getPerspectiveTransform(original_points, destination_points)

# 使用cv2.perspectiveTransform直接計算座標
pt =  np.array([[[400,560]]], dtype=np.float32)
dst_pt = cv2.perspectiveTransform(pt, M)
dst_pt = dst_pt.astype(int)
dst_pt = tuple(dst_pt[0,0,].tolist())

# 使用相对位置計算座標
center_pt_warpped = np.array([[[warpped_img.shape[1] / 2, warpped_img.shape[0] / 2]]], dtype=np.float32)
dst_pt_center = cv2.perspectiveTransform(center_pt_warpped, M)
dst_pt_center = dst_pt_center.astype(int)
dst_pt_center = tuple(dst_pt_center[0,0,].tolist())

# warp perspective
warpped_img = cv2.warpPerspective(original_img, M, (600,400))

# 在变换后的图像中标记两个点
cv2.circle(warpped_img, dst_pt, 7, (0,255,255), -1)
cv2.circle(warpped_img, dst_pt_center, 7, (255,0,0), -1)
cv2.imshow('original', original_img)
cv2.imshow('warpped', warpped_img)
cv2.waitKey(0)

运行这段代码,我们可以在原图和变换后的图像中看到标记的两个点,这两个点是同一个点在透视变换前后,在图像中的位置。