我有一个由大小为n * n
我创建了一个变换矩阵
M = cv2.getPerspectiveTransform(...)
我可以使用
在M
中定义的形状转换图像
cv2.warpPerspective(image, M, image_shape)
根据this,我应该能够将矩阵与一个点相乘,并在转换后得到该点的新位置。我试过了:
point = [100, 100, 0]
x, y, z = M.dot(point)
但是我得到了错误的结果。 (在这种情况下[112.5 12.5 0])
我做错了什么?
为了更清晰,我在做什么:
我有这个图像,不同图层上的线条和正方形
我扭曲线条并得到这个:
现在我想得到像这样放置方块的坐标:
我所拥有的是用于线条的经线矩阵,以及第一张图片中方块的坐标
注意:一个选项是创建一个带有单个点的图像,只需使用第一个方法对其进行扭曲,然后在新图像中找到非零单元格。我希望找到比这更惯用的东西,希望
答案 0 :(得分:4)
齐次坐标的最后一个点永远不应该为0,除非它专门引用无穷远处的点。出于您的目的,它应该是1
。您还应该将转换后的像素x
和y
按最后一个值z
缩放。请参阅我的回答here以获得深入的解释。
单点:
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)
产生具有随机噪声的图像,白色方框和绿色轮廓,显示应用于方框轮廓的变换。