一个齐次坐标的最后一位不应该为0,除非它特别指代了一个无穷远点。对于您的目的,它应该是1。您还应该通过最后一个值z来缩放转换后的像素x和y。请参见我在
这里给出的详细解释。
对于单个点:
point = np.array([100, 100])
homg_point = [point[0], point[1], 1]
transf_homg_point = M.dot(homg_point)
transf_homg_point /= transf_homg_point[2]
transf_point = transf_homg_point[:2]
对于多个点(使用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
img = np.random.rand(512,512,3)
img[128:384, 64:196] = [1,1,1]
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.]])
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]
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)
cv2.polylines(img, [transf_rect], isClosed=True, color=[0,1,0], thickness=2)
产生带有随机噪声、白色方框和绿色轮廓的图像,显示应用于方框轮廓的变换。
point
的最后一个元素应该是1,而您使用了0!!... - api55