基于OpenCV的透视图转化为不同平面

小白学视觉

共 5041字,需浏览 11分钟

 · 2021-03-08

点击上方小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达


由于相机技术的进步,相机能够以各种角度和视角拍摄照片。无人机的广角,鸟瞰图,侧视图等不同的角度,鱼眼镜头之类的不同相机镜头将场景投射到相机图像平面上的方式与对象在世界上的实际位置不同。这种现象被称为摄影中的透视变形。


雷梅霍夫写到“镜子中物体的距离小于它们的实际距离”,总是在侧视镜其中大部分是倾斜,稍弯曲。由于这种曲率,我们在镜子中看到的图像中会发生透视失真。


形式上,透视失真是对象及其周围区域的扭曲或变形,由于附近和远处特征的相对比例,该扭曲或变形与对象在正常焦距下的外观明显不同。我们将介绍如何根据给定的2D摄影机图像(在特定的假设下)校正这些变形,以找出物体在世界上的实际位置。


首先,我们必须了解世界上的3d对象如何投影到相机的图像平面上

从本质上讲,光线是通过相机的针孔投射到物体上的。当从物体反射时,该光会投射在相机内部的图像平面上,并给出倒置的图像。为了获得实际视图,请将该图像平面反转(上图中的虚拟图像平面)。


无需深入研究数学细节,就可以将对象在3d世界中的坐标转换为2d平面平面。


在数学上,将3d坐标乘以3x4矩阵(称为透视矩阵)可得到图像平面中的2d坐标。

使用3x4透视矩阵将3d世界坐标系中的点(x,y,z)转换为2d相机图像平面上的点(u,v)。


但是在这篇文章中,我们想找到一个从2d图像平面到世界坐标的矩阵。直观地讲,这是不可能的,因为在2d图像平面中,我们丢失了深度尺寸,并且在没有任何额外知识的情况下也无法恢复3d尺寸(这就是RGB-D相机退出的原因)。同样在数学上,3x4投影矩阵不是正方形的,因此是不可逆的。


但是,如果我们仅对固定z的对象的(x,y)世界坐标感兴趣,则可以找到这些坐标。例如,如果我们在无人机的顶部有一个安全摄像机,并且我们想从摄像机图像中知道人在地板上的实际位置(将固定z = 0作为地板平面),则有可能有两种方法可以做到这一点:


1.使用反透视矩阵


如果需要(x,y)世界坐标的平面在系统的z = 0处,则地板平面上的任何点都将具有坐标<x,y,0>,这有效地消除了第三个坐标的影响透视矩阵从等式1开始的一列。现在,透视矩阵P可以简化为3x3矩阵,因此变为可逆的(如下所示)。



现在要从(u,v)得到(x,y),我们只需要找到3x3透视矩阵P的逆,就可以从像平面找到地板平面上的对应点。但是,如果我们想在z不等于0的任意平面上找到(x,y)坐标,该怎么办。我们可以使用Homography来实现这一点。


2.使用单应矩阵


单应矩阵涉及从一个平面到另一平面的变换。本质上,如果我们在一个平面中具有<u,v>点,而在另一平面中具有<x,y>,则从<u,v>到<x,y>的转换可以写为


但是要获得单应性矩阵,我们必须在一个平面上至少需要4个点,而在另一平面上至少需要它们的映射点。给定透视矩阵P,我们可以轻松找到任意3d世界平面(保持固定的z)和2d平面之间的4个对应点。

在OpenCV中,可以cv2.findHomography通过在源平面和目标平面中提供4个或更多点来使用函数查找单应矩阵。


下面是使用OpenCV的代码。

import cv2import numpy as np
defget_inverse_pespective(perspective_matrix: np.array)-> np.array: """ This method calculates the inverse of prespective matrix by homography. -Takes 4 random points on the floor plane(destination_plane) and calculates thecorresponding points onthe camera image plane(src_plane) using perspective matrix. -Calculates the Homography matrix to map any point in image plane to floorplane. Parameters ---------- perspective_matrix: 3 x 4 camera prespective matrix to convert 3dhomogeneous world coordinates to 2dhomogeneous camera coordinates. Returns ---------- 3x3homography matrix for moving from 2d homogeneous image plane to world floorplane(at z=0)
""" #Take 5 homogenous points on the floor(Unit is in Meters) pts_dst = np.array([[0,0,0,1], [0,1,0,1], [1,0,0,1], [1,1,0,1], [0,0,0,1] ]) #Obtain respective homogenous points on the image plane pts_src = (perspective_matrix @ pts_dst.T).T
#convert homogenous coordinates to cartesian coorndinates pts_src_cart = np.array([[x/w, y/w] for x,y,w in pts_src]) pts_dst_cart = np.array([[x/w, y/w] for x,y,z,w in pts_dst])
#find the 3x3 Homography Matrix for transforming image plane to floorplane H,status = cv2.findHomography(pts_src_cart, pts_dst_cart) return H
def project_to_floor(image_coordinates:List[int], H: np.array) -> List[int]: """ This method takes the Homography matrix and the 2d image cartesiancoordinates. It returns the (x, y) cartesian coordinates in 3d cartesian world coordinates on floorplane(at z=0). Notice that z coordinate is omitted here and added inside the tracking funtion.
Parameters ---------- image_coordinates: 2d pixel coordinates (x,y) h:3x3 Homography matrix np.array[3x3] Returns ---------- floor_coordinates: List of x, y coordinates in 3d world of same pixel onfloor plane i.e. (x,y,z) Considering z=0 and ommitted here. """ #adding 1 for homogenous coordinate system x,y, w = H @ np.array([[*image_coordinates, 1]]).T return [x/w, y/w]
p = np.random.rand(3,4)H = get_inverse_pespective(p)src_point = (5,10)dst_point = project_to_floor(src_point, H)

一旦获得了单应性矩阵,就可以使用等式2从像平面移动到所需平面。这些方法并不暗示有关世界坐标系中沿z轴的位置的任何信息,并认为它是固定的。


需要注意:

1.对于在世界坐标中从“图像”平面到固定平面的“透视”转换,可以使用两种方法。

2.如果平面方程为z = 0,则可以通过完全忽略第3列将3x4透视矩阵简化为3x3矩阵,并且可以使用此3x3矩阵的逆矩阵。

3.对于任何其他任意平面,应使用单应性矩阵。为了找到单应矩阵,该cv.findhomography方法在两个平面中至少需要4个对应点。


下载1:OpenCV-Contrib扩展模块中文版教程
在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲
小白学视觉公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲
小白学视觉公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群


欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~


浏览 32
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报