OpenCV-Python教程:48.核面幾何

基礎(chǔ)概念

當我們使用針孔攝像機拍攝圖像時,我們會丟失重要信息据途,圖像的深度⌒鸬椋或者圖像每個點離攝像機有多遠颖医,因為這是一個3D到2D的轉(zhuǎn)換。所以我們是否能找到深度信息就變得很重要裆蒸∪巯簦回答是使用多個攝像機。我們的眼睛也是類似的方法,我們使用兩個攝像機(雙眼)佛致,這被叫做立體影像贮缕。所以我們看看OpenCV提供了什么。

在更進一步之前俺榆,我們先明白一些多視幾何的基礎(chǔ)概念感昼。在本節(jié)里,我們會用核面幾何處理罐脊《ㄉぃ看下面的圖像顯示了兩個攝像機對同一個場景拍攝圖像的基本設(shè)置。

如果我們只用左邊的攝像機萍桌,我們沒法找到點x的對應3D點宵溅。因為線OX上的每一個點在圖像平面都投影到同一個點。但是如果加上右邊的攝像機梗夸,現(xiàn)在OX線上的不同點在右邊的平面投影到了不同的點(x')层玲。所以用兩個圖像,我們可以三角測量正確的3D點反症。這就是所有想法辛块。

在右邊平面上不同點投影出來的直線(l')。我們叫做點x對應的極線铅碍。它表示润绵,要找到右邊圖像里的點x,沿著這根直線找就行胞谈。它應該在這條線上的某出(這么想尘盼,要找到在另一張圖上的對應點,你不需要搜索整張圖片烦绳,只需要在這根直線上找就行卿捎。所以它提供了更好的性能和準確性)。這被叫做極限約束径密。類似的所有的點都會在另一張圖上有對應的極線午阵。平面XOO'背景叫做偏斜面。

O和O'是攝像機中心享扔,從上面可以看到右邊攝像機的O'的投影可以在左邊圖片看到底桂,e點。這被叫做極點惧眠。極點是通過兩個攝像機中心的直線與圖片平面的焦點籽懦。類似的,e'是左邊攝像機的極點氛魁。在某些情況下暮顺,你沒法在圖像內(nèi)定位極點厅篓,他們可能在圖像外(這表示攝像機沒法看見彼此)。

所有的極線都通過極點拖云。所以要找到極點的位置贷笛,我們可以找多條極線应又,然后找他們的交點宙项。

我們要找到極線和極點,需要兩個東西株扛,基礎(chǔ)矩陣(F)和本質(zhì)矩陣(E)尤筐。本質(zhì)矩陣包含平移和旋轉(zhuǎn)的信息,描述了第二個攝像機相對于第一個在全局坐標系里的位置洞就∨璺保看下圖:

基礎(chǔ)矩陣包含了和本質(zhì)矩陣一樣的信息,另外還有兩個攝像機內(nèi)聯(lián)信息旬蟋,這樣我們可以把兩個攝像機在像素坐標系內(nèi)關(guān)聯(lián)起來油昂。(如果我們使用修正過的圖像并按焦距把點分開正規(guī)化了,F(xiàn)=E)倾贰。簡單的說冕碟,基礎(chǔ)矩陣F把一個圖像里的點映射到另一個圖里的線(極線)。這是通過兩個圖像里的匹配點計算的匆浙。最少需要8個點來得到基礎(chǔ)矩陣(使用8點算法)安寺,最好能有多個點來使用RANSAC來得到更健壯得到結(jié)果。

編碼:

所以我們需要找到兩張圖像里盡可能多的匹配來找基礎(chǔ)矩陣首尼。為了這個挑庶,我們使用基于FLANN匹配子的SIFT描述子和比率測試

import cv2
import numpy as np
from matplotlib import pyplot as plt

img1 = cv2.imread('myleft.jpg',0)? #queryimage # left image
img2 = cv2.imread('myright.jpg',0) #trainimage # right image

sift = cv2.SIFT()

# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1,None)
kp2, des2 = sift.detectAndCompute(img2,None)

# FLANN parameters
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks=50)

flann = cv2.FlannBasedMatcher(index_params,search_params)
matches = flann.knnMatch(des1,des2,k=2)

good = []
pts1 = []
pts2 = []

# ratio test as per Lowe's paper
for i,(m,n) in enumerate(matches):
? ? if m.distance < 0.8*n.distance:
? ? ? ? good.append(m)
? ? ? ? pts2.append(kp2[m.trainIdx].pt)
? ? ? ? pts1.append(kp1[m.queryIdx].pt)

現(xiàn)在我們有兩個圖片里最佳匹配的列表,我們來找基礎(chǔ)矩陣

pts1 = np.int32(pts1)
pts2 = np.int32(pts2)
F, mask = cv2.findFundamentalMat(pts1,pts2,cv2.FM_LMEDS)

# We select only inlier points
pts1 = pts1[mask.ravel()==1]
pts2 = pts2[mask.ravel()==1]

下面我們找極線软能,極線在第一個圖像里對應的點畫在第二個圖像里迎捺。我們得到線的數(shù)組,我們定義一個新的函數(shù)來在圖像里畫這些線查排。

def drawlines(img1,img2,lines,pts1,pts2):
? ? ''' img1 - image on which we draw the epilines for the points in img2?lines - corresponding epilines '''
? ? r,c = img1.shape
? ? img1 = cv2.cvtColor(img1,cv2.COLOR_GRAY2BGR)
? ? img2 = cv2.cvtColor(img2,cv2.COLOR_GRAY2BGR)
? ? for r,pt1,pt2 in zip(lines,pts1,pts2):
? ? ? ? color = tuple(np.random.randint(0,255,3).tolist())
? ? ? ? x0,y0 = map(int, [0, -r[2]/r[1] ])
? ? ? ? x1,y1 = map(int, [c, -(r[2]+r[0]*c)/r[1] ])
? ? ? ? img1 = cv2.line(img1, (x0,y0), (x1,y1), color,1)
? ? ? ? img1 = cv2.circle(img1,tuple(pt1),5,color,-1)
? ? ? ? img2 = cv2.circle(img2,tuple(pt2),5,color,-1)
? ? return img1,img2

現(xiàn)在我們找同時在兩個圖像里的極線并畫出他們:

# Find epilines corresponding to points in right image (second image) and
# drawing its lines on left image

lines1 = cv2.computeCorrespondEpilines(pts2.reshape(-1,1,2), 2,F)
lines1 = lines1.reshape(-1,3)
img5,img6 = drawlines(img1,img2,lines1,pts1,pts2)

# Find epilines corresponding to points in left image (first image) and
# drawing its lines on right image
lines2 = cv2.computeCorrespondEpilines(pts1.reshape(-1,1,2), 1,F)
lines2 = lines2.reshape(-1,3)
img3,img4 = drawlines(img2,img1,lines2,pts2,pts1)

plt.subplot(121),plt.imshow(img5)
plt.subplot(122),plt.imshow(img3)
plt.show()

下面是我們得到的結(jié)果

你可以看到在左邊的圖像里所有的極線匯聚在圖像外的點凳枝。那個匯聚點就是極點。

要得到更好的結(jié)果雹嗦,應該用有好的分辨率的圖像范舀,有很多非平面的點

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市了罪,隨后出現(xiàn)的幾起案子锭环,更是在濱河造成了極大的恐慌,老刑警劉巖泊藕,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辅辩,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機玫锋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門蛾茉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人撩鹿,你說我怎么就攤上這事谦炬。” “怎么了节沦?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵键思,是天一觀的道長。 經(jīng)常有香客問我甫贯,道長吼鳞,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任叫搁,我火速辦了婚禮赔桌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘渴逻。我一直安慰自己疾党,他們只是感情好,可當我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布裸卫。 她就那樣靜靜地躺著仿贬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪墓贿。 梳的紋絲不亂的頭發(fā)上茧泪,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天,我揣著相機與錄音聋袋,去河邊找鬼队伟。 笑死,一個胖子當著我的面吹牛幽勒,可吹牛的內(nèi)容都是我干的嗜侮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼啥容,長吁一口氣:“原來是場噩夢啊……” “哼锈颗!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起咪惠,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤击吱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后遥昧,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體覆醇,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡朵纷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了永脓。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片袍辞。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖常摧,靈堂內(nèi)的尸體忽然破棺而出搅吁,到底是詐尸還是另有隱情,我是刑警寧澤排宰,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布似芝,位于F島的核電站那婉,受9級特大地震影響板甘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜详炬,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一盐类、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧呛谜,春花似錦在跳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至聚凹,卻和暖如春割坠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背妒牙。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工彼哼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人湘今。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓敢朱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親摩瞎。 傳聞我的和親對象是個殘疾皇子拴签,可洞房花燭夜當晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容