逆透视变换?
Inverse Perspective Transform?
我正在尝试从给定图像中找到鸟瞰图像。我还有将其转换为鸟瞰平面所需的旋转和平移(也是固有矩阵)。我的目标是找到一个逆单应矩阵(3x3)。
rotation_x = np.asarray([[1,0,0,0],
[0,np.cos(R_x),-np.sin(R_x),0],
[0,np.sin(R_x),np.cos(R_x),0],
[0,0,0,1]],np.float32)
translation = np.asarray([[1, 0, 0, 0],
[0, 1, 0, 0 ],
[0, 0, 1, -t_y/(dp_y * np.sin(R_x))],
[0, 0, 0, 1]],np.float32)
intrinsic = np.asarray([[s_x * f / (dp_x ),0, 0, 0],
[0, 1 * f / (dp_y ) ,0, 0 ],
[0,0,1,0]],np.float32)
#The Projection matrix to convert the image coordinates to 3-D domain from (x,y,1) to (x,y,0,1); Not sure if this is the right approach
projection = np.asarray([[1, 0, 0],
[0, 1, 0],
[0, 0, 0],
[0, 0, 1]], np.float32)
homography_matrix = intrinsic @ translation @ rotation @ projection
inv = cv2.warpPerspective(source_image, homography_matrix,(w,h),flags = cv2.INTER_CUBIC | cv2.WARP_INVERSE_MAP)
我的问题是,这是正确的方法吗,因为我可以手动设置合适的 ty,rx
,但不适用于提供的 (ty,rx)
。
第一个前提:您的鸟瞰图仅对图像中的一个特定平面是正确的,因为单应性只能映射平面(包括无限远处的平面,对应于纯相机旋转)。
第二个前提:如果你能在第一张图片中识别出一个四边形,它是一个矩形在世界上的投影,你就可以直接计算将四边形映射到矩形的单应性(即 "birds's eye view"四边形的),并用它扭曲图像,设置比例,使图像扭曲到所需的大小。无需使用相机内在函数。示例:您有一个矩形 windows 建筑物的图像,并且您知道世界上这些 windows 的 width/height 比例。
有时候你找不到矩形,但是你的相机是校准过的,所以你描述的问题就出现了。让我们来计算一下。假设您在给定图像中观察到的平面在世界坐标中为 Z=0
。设 K
为 3x3 固有相机矩阵,[R, t]
为表示 XYZ 世界坐标系中相机姿势的 3x4 矩阵,因此如果 Pc
和 Pw
分别表示相同的 3D 点在相机和世界坐标中,它是 Pc = R*Pw + t = [R, t] * [Pw.T, 1].T
,其中 .T 表示转置。那么你可以把相机投影写成:
s * p = K * [R, t] * [Pw.T, 1].T
其中 s
是任意比例因子,p
是 Pw
投影到的像素。但是如果Pw=[X, Y, Z].T
在Z=0
平面上,R
的第3列只乘零,所以我们可以忽略它。如果我们再用 r1
和 r2
表示 R
的前两列,我们可以将上面的等式重写为:
s * p = K * [r1, r2, t] * [X, Y, 1].T
但是K * [r1, r2, t]
是一个3x3矩阵,将3D平面上的点转换为相机平面上的点,所以它是单应性的。
如果平面不是Z=0,你可以重复相同的参数,用[R, t] * inv([Rp, tp])替换[R, t],其中[Rp, tp]是将平面上的框架映射到世界框架的坐标变换,平面法线为 Z 轴。
最后,为了获得鸟瞰图,你 select 旋转 R,其第三列(相机框架中世界 Z 轴的分量)与平面法线相反。
我正在尝试从给定图像中找到鸟瞰图像。我还有将其转换为鸟瞰平面所需的旋转和平移(也是固有矩阵)。我的目标是找到一个逆单应矩阵(3x3)。
rotation_x = np.asarray([[1,0,0,0],
[0,np.cos(R_x),-np.sin(R_x),0],
[0,np.sin(R_x),np.cos(R_x),0],
[0,0,0,1]],np.float32)
translation = np.asarray([[1, 0, 0, 0],
[0, 1, 0, 0 ],
[0, 0, 1, -t_y/(dp_y * np.sin(R_x))],
[0, 0, 0, 1]],np.float32)
intrinsic = np.asarray([[s_x * f / (dp_x ),0, 0, 0],
[0, 1 * f / (dp_y ) ,0, 0 ],
[0,0,1,0]],np.float32)
#The Projection matrix to convert the image coordinates to 3-D domain from (x,y,1) to (x,y,0,1); Not sure if this is the right approach
projection = np.asarray([[1, 0, 0],
[0, 1, 0],
[0, 0, 0],
[0, 0, 1]], np.float32)
homography_matrix = intrinsic @ translation @ rotation @ projection
inv = cv2.warpPerspective(source_image, homography_matrix,(w,h),flags = cv2.INTER_CUBIC | cv2.WARP_INVERSE_MAP)
我的问题是,这是正确的方法吗,因为我可以手动设置合适的 ty,rx
,但不适用于提供的 (ty,rx)
。
第一个前提:您的鸟瞰图仅对图像中的一个特定平面是正确的,因为单应性只能映射平面(包括无限远处的平面,对应于纯相机旋转)。
第二个前提:如果你能在第一张图片中识别出一个四边形,它是一个矩形在世界上的投影,你就可以直接计算将四边形映射到矩形的单应性(即 "birds's eye view"四边形的),并用它扭曲图像,设置比例,使图像扭曲到所需的大小。无需使用相机内在函数。示例:您有一个矩形 windows 建筑物的图像,并且您知道世界上这些 windows 的 width/height 比例。
有时候你找不到矩形,但是你的相机是校准过的,所以你描述的问题就出现了。让我们来计算一下。假设您在给定图像中观察到的平面在世界坐标中为 Z=0
。设 K
为 3x3 固有相机矩阵,[R, t]
为表示 XYZ 世界坐标系中相机姿势的 3x4 矩阵,因此如果 Pc
和 Pw
分别表示相同的 3D 点在相机和世界坐标中,它是 Pc = R*Pw + t = [R, t] * [Pw.T, 1].T
,其中 .T 表示转置。那么你可以把相机投影写成:
s * p = K * [R, t] * [Pw.T, 1].T
其中 s
是任意比例因子,p
是 Pw
投影到的像素。但是如果Pw=[X, Y, Z].T
在Z=0
平面上,R
的第3列只乘零,所以我们可以忽略它。如果我们再用 r1
和 r2
表示 R
的前两列,我们可以将上面的等式重写为:
s * p = K * [r1, r2, t] * [X, Y, 1].T
但是K * [r1, r2, t]
是一个3x3矩阵,将3D平面上的点转换为相机平面上的点,所以它是单应性的。
如果平面不是Z=0,你可以重复相同的参数,用[R, t] * inv([Rp, tp])替换[R, t],其中[Rp, tp]是将平面上的框架映射到世界框架的坐标变换,平面法线为 Z 轴。
最后,为了获得鸟瞰图,你 select 旋转 R,其第三列(相机框架中世界 Z 轴的分量)与平面法线相反。