基于OpenCV的透視圖轉(zhuǎn)化為不同平面
點(diǎn)擊上方“小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時(shí)間送達(dá)

由于相機(jī)技術(shù)的進(jìn)步,相機(jī)能夠以各種角度和視角拍攝照片。無人機(jī)的廣角,鳥瞰圖,側(cè)視圖等不同的角度,魚眼鏡頭之類的不同相機(jī)鏡頭將場(chǎng)景投射到相機(jī)圖像平面上的方式與對(duì)象在世界上的實(shí)際位置不同。這種現(xiàn)象被稱為攝影中的透視變形。
雷梅霍夫?qū)懙健扮R子中物體的距離小于它們的實(shí)際距離”,總是在側(cè)視鏡其中大部分是傾斜,稍彎曲。由于這種曲率,我們?cè)阽R子中看到的圖像中會(huì)發(fā)生透視失真。
形式上,透視失真是對(duì)象及其周圍區(qū)域的扭曲或變形,由于附近和遠(yuǎn)處特征的相對(duì)比例,該扭曲或變形與對(duì)象在正常焦距下的外觀明顯不同。我們將介紹如何根據(jù)給定的2D攝影機(jī)圖像(在特定的假設(shè)下)校正這些變形,以找出物體在世界上的實(shí)際位置。
首先,我們必須了解世界上的3d對(duì)象如何投影到相機(jī)的圖像平面上。

從本質(zhì)上講,光線是通過相機(jī)的針孔投射到物體上的。當(dāng)從物體反射時(shí),該光會(huì)投射在相機(jī)內(nèi)部的圖像平面上,并給出倒置的圖像。為了獲得實(shí)際視圖,請(qǐng)將該圖像平面反轉(zhuǎn)(上圖中的虛擬圖像平面)。
無需深入研究數(shù)學(xué)細(xì)節(jié),就可以將對(duì)象在3d世界中的坐標(biāo)轉(zhuǎn)換為2d平面平面。

在數(shù)學(xué)上,將3d坐標(biāo)乘以3x4矩陣(稱為透視矩陣)可得到圖像平面中的2d坐標(biāo)。

使用3x4透視矩陣將3d世界坐標(biāo)系中的點(diǎn)(x,y,z)轉(zhuǎn)換為2d相機(jī)圖像平面上的點(diǎn)(u,v)。
但是在這篇文章中,我們想找到一個(gè)從2d圖像平面到世界坐標(biāo)的矩陣。直觀地講,這是不可能的,因?yàn)樵?d圖像平面中,我們丟失了深度尺寸,并且在沒有任何額外知識(shí)的情況下也無法恢復(fù)3d尺寸(這就是RGB-D相機(jī)退出的原因)。同樣在數(shù)學(xué)上,3x4投影矩陣不是正方形的,因此是不可逆的。
但是,如果我們僅對(duì)固定z的對(duì)象的(x,y)世界坐標(biāo)感興趣,則可以找到這些坐標(biāo)。例如,如果我們?cè)跓o人機(jī)的頂部有一個(gè)安全攝像機(jī),并且我們想從攝像機(jī)圖像中知道人在地板上的實(shí)際位置(將固定z = 0作為地板平面),則有可能有兩種方法可以做到這一點(diǎn):
如果需要(x,y)世界坐標(biāo)的平面在系統(tǒng)的z = 0處,則地板平面上的任何點(diǎn)都將具有坐標(biāo)<x,y,0>,這有效地消除了第三個(gè)坐標(biāo)的影響透視矩陣從等式1開始的一列。現(xiàn)在,透視矩陣P可以簡(jiǎn)化為3x3矩陣,因此變?yōu)榭赡娴模ㄈ缦滤荆?/span>

現(xiàn)在要從(u,v)得到(x,y),我們只需要找到3x3透視矩陣P的逆,就可以從像平面找到地板平面上的對(duì)應(yīng)點(diǎn)。但是,如果我們想在z不等于0的任意平面上找到(x,y)坐標(biāo),該怎么辦。我們可以使用Homography來實(shí)現(xiàn)這一點(diǎn)。
單應(yīng)矩陣涉及從一個(gè)平面到另一平面的變換。本質(zhì)上,如果我們?cè)谝粋€(gè)平面中具有<u,v>點(diǎn),而在另一平面中具有<x,y>,則從<u,v>到<x,y>的轉(zhuǎn)換可以寫為

但是要獲得單應(yīng)性矩陣,我們必須在一個(gè)平面上至少需要4個(gè)點(diǎn),而在另一平面上至少需要它們的映射點(diǎn)。給定透視矩陣P,我們可以輕松找到任意3d世界平面(保持固定的z)和2d平面之間的4個(gè)對(duì)應(yīng)點(diǎn)。
在OpenCV中,可以cv2.findHomography通過在源平面和目標(biāo)平面中提供4個(gè)或更多點(diǎn)來使用函數(shù)查找單應(yīng)矩陣。
下面是使用OpenCV的代碼。
import cv2import numpy as npdefget_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 pointsonthe 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 to2dhomogeneous 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 planepts_src = (perspective_matrix @ pts_dst.T).T#convert homogenous coordinates to cartesian coorndinatespts_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 floorplaneH,status = cv2.findHomography(pts_src_cart, pts_dst_cart)return Hdef 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 omittedhere 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 andommitted here."""#adding 1 for homogenous coordinate systemx,y, w = H @ np.array([[*image_coordinates, 1]]).Treturn [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)
一旦獲得了單應(yīng)性矩陣,就可以使用等式2從像平面移動(dòng)到所需平面。這些方法并不暗示有關(guān)世界坐標(biāo)系中沿z軸的位置的任何信息,并認(rèn)為它是固定的。
需要注意:
1.對(duì)于在世界坐標(biāo)中從“圖像”平面到固定平面的“透視”轉(zhuǎn)換,可以使用兩種方法。
2.如果平面方程為z = 0,則可以通過完全忽略第3列將3x4透視矩陣簡(jiǎn)化為3x3矩陣,并且可以使用此3x3矩陣的逆矩陣。
3.對(duì)于任何其他任意平面,應(yīng)使用單應(yīng)性矩陣。為了找到單應(yīng)矩陣,該cv.findhomography方法在兩個(gè)平面中至少需要4個(gè)對(duì)應(yīng)點(diǎn)。
交流群
歡迎加入公眾號(hào)讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動(dòng)駕駛、計(jì)算攝影、檢測(cè)、分割、識(shí)別、醫(yī)學(xué)影像、GAN、算法競(jìng)賽等微信群(以后會(huì)逐漸細(xì)分),請(qǐng)掃描下面微信號(hào)加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請(qǐng)按照格式備注,否則不予通過。添加成功后會(huì)根據(jù)研究方向邀請(qǐng)進(jìn)入相關(guān)微信群。請(qǐng)勿在群內(nèi)發(fā)送廣告,否則會(huì)請(qǐng)出群,謝謝理解~

