openCV:如何使用getPerspectiveTransform函数

8

我有一个由 n * n 的矩阵表示的图像。

我创建了一个变换矩阵。

M = cv2.getPerspectiveTransform(...)

我可以使用 M 中定义的形状对图像进行转换,方法如下:

cv2.warpPerspective(image, M, image_shape)

根据这里的说明,我应该能够将矩阵与点相乘,并在变换后获得该点的新位置。我尝试了一下:
point = [100, 100, 0]
x, y, z = M.dot(point)

但我得到了错误的结果。(在这种情况下[112.5 12.5 0])

我做错了什么?


为了更清楚地说明,这是我的做法:

我有这张图片,带有不同图层上的线和正方形

before warp

我扭曲了那些线,得到了这个结果:

warped lines

现在,我想要得到放置正方形的坐标,就像这样:

expected

我所拥有的是用于那些线的扭曲矩阵,以及第一张图片中正方形的坐标


注意:一种方法是创建一个只有一个点的图像,将其与第一种方法一起扭曲,并在新图像中找到非零单元格。我正在寻找比那更具语言特色的方法。


可能是[Opencv单应性]的重复问题,用于从像素xy坐标中找到全局xy坐标。 - alkasm
2
如果您查看您提供的链接,它会说point的最后一个元素应该是1,而您使用了0!!... - api55
1个回答

10
一个齐次坐标的最后一位不应该为0,除非它特别指代了一个无穷远点。对于您的目的,它应该是1。您还应该通过最后一个值z来缩放转换后的像素x和y。请参见我在这里给出的详细解释。
对于单个点:
point = np.array([100, 100])
homg_point = [point[0], point[1], 1] # homogeneous coords
transf_homg_point = M.dot(homg_point) # transform
transf_homg_point /= transf_homg_point[2] # scale
transf_point = transf_homg_point[:2] # remove Cartesian coords

对于多个点(使用OpenCV标准方式写点):

points = np.array([[[100, 100]], [[150,100]], [[150,150]], [[150,100]]])
homg_points = np.array([[x, y, 1] for [[x, y]] in points]).T
transf_homg_points = M.dot(homg_points)
transf_homg_points /= transf_homg_points[2]
transf_points = np.array([[[x,y]] for [x, y] in transf_homg_points[:2].T])

使用从OpenCV函数中获取的点的最小示例:

import numpy as np 
import cv2

# generate random noise image, draw a white box
img = np.random.rand(512,512,3)
img[128:384, 64:196] = [1,1,1]

# create a Euclidean transformation which rotates by 30 deg + translates by (100,100)
theta = 30*np.pi/180
H = np.array([
    [ np.cos(theta),np.sin(theta),100.],
    [-np.sin(theta),np.cos(theta),100.],
    [0.,0.,1.]])

# find the white box
bin_img = cv2.inRange(img, np.ones(3), np.ones(3))
contour_points = cv2.findContours(bin_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[1][0]

# transform the location of the box
homg_points = np.array([[x, y, 1] for [[x, y]] in contour_points]).T
transf_homg_points = H.dot(homg_points)
transf_homg_points /= transf_homg_points[2]
transf_rect = np.array([[[x,y]] for [x, y] in transf_homg_points[:2].T], dtype=np.int32)

# draw the transformed box as a green outline
cv2.polylines(img, [transf_rect], isClosed=True, color=[0,1,0], thickness=2)

产生带有随机噪声、白色方框和绿色轮廓的图像,显示应用于方框轮廓的变换。 Transformed contour

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接