




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、一個(gè)好的計(jì)算機(jī)視覺(jué)算法如果沒(méi)有偉大健壯的功能以及廣泛的普遍化和一個(gè)堅(jiān)實(shí)的數(shù)學(xué)基礎(chǔ)是不完整的。所有的這些優(yōu)點(diǎn)伴隨著主要由TimCootes開(kāi)發(fā)的主動(dòng)表觀模型(Active Appearance Models)。這一章將教給你怎樣使用OpenCV創(chuàng)建一個(gè)你自己的主動(dòng)表觀模型以及怎樣在一個(gè)給出的圖像幀中使用它搜索模型所在的最鄰近位置。而且你將學(xué)習(xí)如何使用POSIT算法和如何在你的”posed”圖像中擬合你的3D模形。使用這些工具,你將能夠?qū)崟r(shí)地在一個(gè)視頻中跟蹤一個(gè)3D模型。不是很棒嗎?盡管例子的焦點(diǎn)在于頭部姿態(tài),事實(shí)上,任何可變模型可以采用同樣的方法。當(dāng)你讀這些部分,你將碰到下列主題:1、 主動(dòng)表觀
2、模型概述2、 主動(dòng)形狀模型概述3、 模型實(shí)例化運(yùn)行主動(dòng)表觀模型4、 AAM搜索和匹配(或擬合,fitting)5、 POIST下面的列表闡述了本章中你將要碰到的術(shù)語(yǔ):1、 主動(dòng)表觀模型(AAM):一個(gè)對(duì)象的模型,包含著對(duì)象形狀和紋理的統(tǒng)計(jì)信息。它是捕獲對(duì)象形狀和紋理變化的一個(gè)強(qiáng)大的方法。2、 主動(dòng)形狀模型(ASM):對(duì)象形狀的統(tǒng)計(jì)模型。它對(duì)于學(xué)習(xí)形狀變化非常有用。3、 主成分分析(PCA):一個(gè)正交線性變換。它將數(shù)據(jù)轉(zhuǎn)換到一個(gè)新的坐標(biāo)系統(tǒng),滿足:數(shù)據(jù)任何投影產(chǎn)生的最大方差將位于第一個(gè)坐標(biāo)(稱為第一個(gè)主成分),第二個(gè)最大的方差位于第二個(gè)坐標(biāo)上,等等。這個(gè)過(guò)程通常用在降維。當(dāng)最初的問(wèn)題減少了維數(shù),
3、我們可以使用一個(gè)更快的匹配(faster-fitting)算法。4、 三角剖分(DT):對(duì)于平面上的一組點(diǎn)P,它是一個(gè)三角剖分,以使得在三角剖分中P中的任何點(diǎn)都不會(huì)在任何三角形的外接圓內(nèi)。它傾向于避免緊瘦的三角形。三角剖分用來(lái)紋理的映射。5、 仿射變換:任何轉(zhuǎn)換都可以用一個(gè)矩陣相乘跟著一個(gè)矢量的加法的形式來(lái)表示。仿射變換可以用來(lái)紋理的映射。6、 Pose from Orthography and Scaling with Iterations(POSIT):一個(gè)執(zhí)行3D姿態(tài)估計(jì)的計(jì)算機(jī)視覺(jué)算法。主動(dòng)表觀模型概述Active Appearnce Models overview 簡(jiǎn)單地說(shuō),主動(dòng)表觀
4、模型是一個(gè)組合紋理和形狀耦合到一個(gè)有效的搜索算法的參數(shù)化模型,它可以準(zhǔn)確的告訴我們一個(gè)模型在一個(gè)圖像幀中的位置以及如何定位于這個(gè)位置。為了做到這一點(diǎn),我們將以主動(dòng)形狀模型部分開(kāi)始并且將看到它們與標(biāo)記的位置緊密關(guān)聯(lián)。主成分分析和一些實(shí)踐經(jīng)驗(yàn)將在下面的部分更好的描述。那時(shí),我們將能夠從OpenCV的Delaunay函數(shù)的獲得一些幫助并且學(xué)習(xí)一些三角剖分。從那起,在三角紋理變換部分,我們將發(fā)展到應(yīng)用分段的仿射變換并且我們可以從一個(gè)對(duì)象的紋理中獲得信息。當(dāng)我們獲得足夠的背景來(lái)建立一個(gè)好的模型,我們可以在模型的實(shí)例部分應(yīng)用這些技術(shù)。然后,我們將能夠通過(guò)AAM搜索和匹配來(lái)解決反問(wèn)題(the inverse
5、 problem)。對(duì)于2D或許甚至3D圖像匹配,這些算法本身已經(jīng)是非常有用的算法。但是當(dāng)我們能夠運(yùn)用這些算法時(shí),為什么不把它聯(lián)系到POSIT3D模型擬合的另一個(gè)堅(jiān)如磐石的算法呢?投入到POSIT部分(Diving into the POSIT section)我們將獲得足夠的背景來(lái)和它(算法)在OpenCV中一起工作,然后,在下面的部分,我們將學(xué)習(xí)如何耦合它的一個(gè)頭部模型。這樣,我們可以使用一個(gè)3D模型來(lái)擬合已匹配的2D圖像幀。并且如果一個(gè)強(qiáng)烈的讀者想知道這將把我們帶到哪里,這正是用一個(gè)幀到幀的方式組合AAM和Posit,通過(guò)可變模型的檢測(cè)來(lái)得到一個(gè)實(shí)時(shí)的3D跟蹤。這些細(xì)節(jié)將在來(lái)至網(wǎng)絡(luò)相機(jī)或
6、者視頻文件的跟蹤部分涉及到。據(jù)說(shuō)一個(gè)照片頂一千個(gè)詞。想象一下如果我們獲得了N個(gè)照片。這樣,我們先前提到的內(nèi)容可以在下面截圖中簡(jiǎn)單的跟蹤。本章算法的概述:給出一個(gè)圖像(先前截圖的左上圖像),我們可以使用主動(dòng)表觀搜索算法來(lái)找到人類頭部的2D姿態(tài)。截圖中右上邊的圖像展示了先前訓(xùn)練好的用在搜索算法中的一個(gè)主動(dòng)表觀模型。找到一個(gè)姿態(tài)之后,POSIT可以用來(lái)推廣這個(gè)結(jié)果到3D姿態(tài)。如果這個(gè)過(guò)程應(yīng)用到了一個(gè)視頻序列,將通過(guò)檢測(cè)獲得3D跟蹤。主動(dòng)形狀模型Active Shape Models像先前提到的,AAM需要一個(gè)形狀模型,這個(gè)角色通過(guò)ASM扮演(Active Shape Models)。在接下來(lái)的部分中
7、,我們將創(chuàng)建一個(gè)ASM,它是形狀變化的統(tǒng)計(jì)模型。這個(gè)形狀模型通過(guò)形狀變化的組合產(chǎn)生。需要一個(gè)標(biāo)記過(guò)的圖像訓(xùn)練集,就像文章形狀模型他們的訓(xùn)練和應(yīng)用(Active Shape Models-Their Training and Application )中描述的那樣。為了建立一個(gè)人臉形狀模型,一些標(biāo)記了人臉關(guān)鍵位置點(diǎn)的圖像用來(lái)概述主要的特征。下面的截圖展示了一個(gè)這樣的例子:一個(gè)人臉上有76個(gè)標(biāo)記,這來(lái)至于MUCT數(shù)據(jù)庫(kù)。這些標(biāo)記通常是手工標(biāo)記的并且概述了一些人臉特征,例如嘴的輪廓,鼻子,眼睛,眉毛和臉的形狀,因?yàn)檫@些特征易于跟蹤。注釋:Procrustes分析:統(tǒng)計(jì)形狀分析的一個(gè)形式,常用于分析一
8、組形狀的分布。Procrustes疊加是通過(guò)最優(yōu)地平移,旋轉(zhuǎn)和一致地縮放對(duì)象來(lái)執(zhí)行的。如果我們有先前提到的圖像集,我們可以產(chǎn)生一個(gè)形狀變化的統(tǒng)計(jì)模型。因?yàn)闃?biāo)記點(diǎn)在對(duì)象上描述了這個(gè)對(duì)象的形狀,如果需要的話,首先我們使用Procrustes分析將這些點(diǎn)集對(duì)齊到一個(gè)坐標(biāo)框架,并且通過(guò)一個(gè)矢量x表示每一個(gè)形狀。然后,我們對(duì)數(shù)據(jù)應(yīng)用主成分分析。那么我們可以使用下面的公式估算任何實(shí)例:x = x + Ps bs在前面的公式中,x是均值形狀,Ps是一組變化的正交模式,bs是一組形狀參數(shù)。好的,為了更好的理解,我們將在本節(jié)的剩余部分創(chuàng)建一個(gè)簡(jiǎn)單的應(yīng)用,這將為我們展示如何處理PCA和形狀模型。使用PCA究竟為什
9、么?因?yàn)楫?dāng)減少我們模型參數(shù)的數(shù)量時(shí),PCA能真正的幫助我們。在本章的后面,我也將看到當(dāng)在一個(gè)給定的圖像中搜索它時(shí),它給我們的幫助是多大。下面的引用來(lái)至于一個(gè)網(wǎng)頁(yè):/wiki/Principal_component_analysis當(dāng)人們從目標(biāo)的豐富信息視點(diǎn)觀察時(shí),PCA可以為用戶提供一個(gè)低維圖像對(duì)象的一個(gè)“影子”。通過(guò)僅使用前幾個(gè)少量主成分就可以完成,這使得轉(zhuǎn)換后的數(shù)據(jù)維數(shù)減少。當(dāng)我們看一個(gè)截圖時(shí),理解更加清晰,如下:先前的截圖展示了一個(gè)中心在(2,3)的多元高斯分布的PCA。所示的向量是協(xié)方差矩陣的特征向量。移動(dòng)向量,這樣它們的尾巴在均值處。如果我
10、們想用一個(gè)單一的參數(shù)表示我們的模型,那么將這些點(diǎn)的特征矢量的方向轉(zhuǎn)移到截圖的右上部分將是一個(gè)好的方法。而且,通過(guò)輕微的改變參數(shù),我們可以推斷數(shù)據(jù)并且獲得類似于我們將要尋找的值。淺嘗PCAGetting the feel of PCA為了獲得PCA是怎么樣幫助我們?nèi)四樐P偷囊粋€(gè)感覺(jué),我們將開(kāi)始一個(gè)主動(dòng)形狀模型并且測(cè)試一些參數(shù)。因?yàn)槿四槞z測(cè)和跟蹤已經(jīng)學(xué)習(xí)了一段時(shí)間,對(duì)于研究的目標(biāo),幾個(gè)人臉數(shù)據(jù)庫(kù)可以在線訪問(wèn)到。我們將使用來(lái)至于IMM數(shù)據(jù)集的一對(duì)樣本。首先,讓我們理解一些OpenCV中PCA類是怎么工作的。我們可以從文獻(xiàn)中得到結(jié)論:PCA類用來(lái)計(jì)算一組矢量的特殊基,它包含通過(guò)一組輸入矢量計(jì)算得到協(xié)方
11、差矩陣的特征矢量。這個(gè)類同樣可以使用project 和backproject方法將矢量投影到新的坐標(biāo)空間或者從新的坐標(biāo)空間反投影到原空間,僅通過(guò)獲取它的前幾個(gè)少量成分就可以精確的估計(jì)這個(gè)新的坐標(biāo)系統(tǒng)。這意味著我們可以使用一個(gè)非常短的子空間中的投影矢量坐標(biāo)組成的矢量來(lái)表示來(lái)至高維空間的原始矢量。因?yàn)樵谏倭砍叨戎捣矫?,我們將要一個(gè)參數(shù)化,我們將要使用的主要方法來(lái)至于類的backproject方法。它帶有投影矢量的主成份坐標(biāo)并且重構(gòu)這些原始坐標(biāo)。如果我們保留所有的成分,我們可以重新獲得原始矢量,但是如果我們僅使用兩個(gè)成分,差別將非常小。這是使用PCA的一個(gè)理由。既然我們想得到圍繞原矢量的變換,我們參
12、數(shù)化尺度將能夠推斷原始數(shù)據(jù)。而且,PCA類可以轉(zhuǎn)換矢量到和從新的坐標(biāo)空間,通過(guò)基本的定義。從數(shù)學(xué)上講,它意味著我們計(jì)算矢量的投影到一個(gè)子空間,該子空間是通過(guò)與協(xié)方差矩陣的主導(dǎo)特征值相對(duì)應(yīng)的一些少量的特征矢量形成,就像我們從文獻(xiàn)中看到的那樣。我們將用landmark標(biāo)記一下我們的人臉圖像來(lái)為點(diǎn)分布模型(point distribution model PDM)產(chǎn)生一個(gè)訓(xùn)練集。如果我們有k個(gè)二維的對(duì)齊標(biāo)記,我們的形狀可以描述為:X = x1, y1, x2, y2, , xk, yk我們需要所有圖像上的一致性的標(biāo)記,這很重要。因此,例如,如果第一個(gè)圖像上嘴的左邊部分的是標(biāo)記3,這將需要所有的其他圖
13、像上的也是標(biāo)記3.現(xiàn)在這些標(biāo)記序列將形成形狀的輪廓,并且一個(gè)給出的訓(xùn)練形狀可以定位為一個(gè)矢量。一般地我們假定這些分布是在這個(gè)空間上的高斯分布,并且我們使用PCA來(lái)計(jì)算所有訓(xùn)練形狀形成的協(xié)方差矩陣的標(biāo)準(zhǔn)化特征矢量和特征值。使用中上的特征矢量,我們創(chuàng)建一個(gè)2k*m的矩陣,我們稱它為P。這樣,每個(gè)特征矢量描述為這個(gè)集合變化的一個(gè)主要模式?,F(xiàn)在我們可以通過(guò)下面的等式定義一個(gè)新的形狀:X = X + Pb這里,X是所有訓(xùn)練圖像的均值形狀我們剛剛計(jì)算的標(biāo)記的每一個(gè)平均以及b是一個(gè)尺度化每一個(gè)主成份的矢量。這引導(dǎo)我們通過(guò)修改b的值創(chuàng)建一個(gè)新的形狀。通常將b設(shè)置在3個(gè)標(biāo)準(zhǔn)差范圍內(nèi),這樣產(chǎn)生的形狀可以落入訓(xùn)練集
14、。下面的截圖展示了用點(diǎn)注釋的嘴標(biāo)記的3個(gè)不同圖像:就像我們?cè)谙惹敖貓D看到的那樣,形狀通過(guò)它們的標(biāo)記序列來(lái)描述。我們可以使用一個(gè)像GIMP或者ImageJ的程序,同樣地在OpenCV中建立一個(gè)簡(jiǎn)單的應(yīng)用,為了標(biāo)記這些訓(xùn)練圖像,我們將假定用戶已經(jīng)完成了這個(gè)過(guò)程并且為所有的訓(xùn)練圖像將這些點(diǎn)保存為x和y標(biāo)記位置的序列,存儲(chǔ)到一個(gè)文本文件中,這在我們的PCA分析中將有用。然而,我們將添加兩個(gè)參數(shù)到這個(gè)文件的第一個(gè)行,即訓(xùn)練圖像的數(shù)目和讀取列的數(shù)目。因此,對(duì)于K個(gè)2D點(diǎn),這個(gè)數(shù)字是2*k。在下面的數(shù)據(jù)中,我們有一個(gè)這個(gè)文件的一個(gè)例子,我們通過(guò)對(duì)IMMdatabase中的三個(gè)圖像的標(biāo)記獲得。這里k是5:3
15、10265 311 303 321 337 310 302 298 265 311255 315 305 337 346 316 305 309 255 315262 316 303 342 332 315 298 299 262 316既然我們已經(jīng)標(biāo)記了圖像,讓我們將這些數(shù)據(jù)帶入我們的形狀模型。首先,導(dǎo)入這些數(shù)據(jù)到一個(gè)矩陣。這個(gè)過(guò)程通過(guò)函數(shù)loadPCA來(lái)完成。下面的代碼片段展示了loadPCA函數(shù)的使用。PCA loadPCA(char* fileName, int& rows, int& cols,Mat& pcaset)FILE* in = fopen(fileName,r);int
16、a;fscanf(in,%d%d,&rows,&cols);pcaset = Mat:eye(rows,cols,CV_64F);int i,j;for(i=0;irows;i+)for(j=0;jcols;j+)fscanf(in,%d,&a);pcaset.at(i,j) = a;PCA pca(pcaset, / pass the data /傳入數(shù)據(jù)Mat(), / we do not have a pre-computed mean vector,/我們沒(méi)有預(yù)計(jì)算均值矢量/ so let the PCA engine compute it/因此讓PCA引擎計(jì)算它CV_PCA_DATA
17、_AS_ROW, / indicate that the vectors /表示這些矢量作為矩陣的行存儲(chǔ)/ are stored as matrix rows/ (use CV_PCA_DATA_AS_COL if the vectors are/ the matrix columns)pcaset.cols/ specify, how many principal components to retain /指定,保留多少主成分);return pca;注意我們的矩陣在pcaset=Mat:eye(rows,cols,CV_64F)中創(chuàng)建并且有足夠的容量來(lái)存儲(chǔ)2*k個(gè)值。兩個(gè)for循環(huán)導(dǎo)入數(shù)
18、據(jù)到這個(gè)矩陣后,調(diào)用帶有一個(gè)數(shù)據(jù)和一個(gè)空矩陣的PCA構(gòu)造器,如果我們希望僅使用它一次,那么這個(gè)矩陣是空矩陣,當(dāng)然也可以是我們預(yù)先計(jì)算的均值矢量。我們同樣指出我們的矢量將作為矩陣的行存儲(chǔ)并且我們希望保持給定行(這里應(yīng)該是列)的數(shù)目和成分?jǐn)?shù)目相同,盡管我們可能僅使用少量的成分。既然我們用我們的訓(xùn)練集填充了我們的PCA對(duì)象,根據(jù)給定的參數(shù),它擁有所需的所有事情來(lái)反投影我們的形狀。我們通過(guò)調(diào)用PCA.backproject來(lái)這樣做,傳遞參數(shù)作為一個(gè)行矢量并且在第二個(gè)參數(shù)中獲得反投影矢量。先前的兩個(gè)截圖展示了根據(jù)滑動(dòng)滾動(dòng)條選擇的兩個(gè)不同形狀的配置參數(shù)。黃色和綠色形狀表明訓(xùn)練數(shù)據(jù)集,紅色形狀反映了選擇參數(shù)
19、產(chǎn)生的形狀。一個(gè)簡(jiǎn)單的應(yīng)用程序可以用來(lái)做主動(dòng)形狀模型實(shí)驗(yàn),對(duì)于模型,它允許用戶嘗試不同的參數(shù)。我們能夠注意到通過(guò)滑動(dòng)滑塊(分別對(duì)應(yīng)于第一個(gè)和第二個(gè)變化模式),僅前兩個(gè)尺度值發(fā)生變化,我們可以獲得一個(gè)形狀,這個(gè)形狀可以非常接近于訓(xùn)練的形狀。當(dāng)我們?cè)贏AM中搜索一個(gè)模型時(shí),這樣的可變性將幫助我們。因?yàn)樗峁┝瞬逯敌螤?。我們將在接下?lái)的部分討論三角剖分,紋理,AAM和AAM-search。三角剖分Trangulaiton 因?yàn)槲覀冋趯ふ业男螤羁赡鼙煌崆?,例如張開(kāi)嘴的一個(gè)實(shí)例,我們需要將我們的紋理映射到一個(gè)均值形狀,然后對(duì)這個(gè)標(biāo)準(zhǔn)化的紋理應(yīng)用PCA。為了這樣做,我們將使用三角剖分。它的概念非常簡(jiǎn)單:
20、我們創(chuàng)建三角形包含我們標(biāo)記的點(diǎn),然而從一個(gè)三角形映射到另外一個(gè)三角形。OpenCV帶有一個(gè)標(biāo)記的函數(shù),叫做cvCreateSubdivDelaunay2D,它創(chuàng)建一個(gè)空的Delaunay三角剖分。你可以僅認(rèn)為這是一個(gè)好的三角剖分,它可以避免瘦長(zhǎng)三角形。注釋:在數(shù)學(xué)和計(jì)算幾何上,平面內(nèi)一個(gè)點(diǎn)集P的Delaunay三角剖分是一個(gè)這樣的一個(gè)三角剖分:P中的每一個(gè)點(diǎn)都不會(huì)落在任何三角形的外接圓內(nèi)。在三角剖分中,Delaunay三角剖分最大化三角形中所有角的最小角。從1934年之后,三角剖分以Boris Delaunay在這個(gè)方面的工作而命名。一個(gè)Delaunay劃分初始化之后,我們將使用cvSubdi
21、vDelaunay2DInsert函數(shù)將這些點(diǎn)填充到三角劃分中。下面的代碼行將說(shuō)明一個(gè)三角剖分的直接使用將是什么樣的:CvMemStorage* storage;CvSubdiv2D* subdiv;CvRect rect = 0, 0, 640, 480 ;storage = cvCreateMemStorage(0);subdiv = cvCreateSubdivDelaunay2D(rect,storage);std:vector points;/initialize points somehow./iterate through points inserting them in the
22、 subdivision/迭代遍歷所有點(diǎn),將它們插入到細(xì)分中for(int i=0;iedges-total;/邊的總數(shù)int elem_size = subdiv-edges-elem_size;/邊的大小,用來(lái)步進(jìn)cvStartReadSeq(CvSeq*)(subdiv-edges), &reader, 0);/初始化閱讀器for(i = 0; i total; i+)CvQuadEdge2D* edge = (CvQuadEdge2D*)(reader.ptr);/將閱讀器的指針初始化為四方邊緣指針if(CV_IS_SET_ELEM(edge)CvSubdiv2DEdge t = (C
23、vSubdiv2DEdge)edge;/獲取四方邊緣的一條邊f(xié)or(j=0;jpt.x), cvRound(pt-pt.y);/將點(diǎn)存儲(chǔ)起來(lái)t = cvSubdiv2DGetEdge(t, triangleDirection);/獲取下一條邊CV_NEXT_SEQ_ELEM(elem_size, reader);/使閱讀器指向下一個(gè)元素給定一個(gè)剖分,我們初始化它的邊讀器(edge reader)稱為cvStartReadSeq函數(shù)。從OpenCV的文獻(xiàn)中,我們引用如下的定義:函數(shù)初始化reader的狀態(tài),然后,所有序列元素,從第一個(gè)到最后一個(gè),在前向閱讀的情況下,可以通過(guò)調(diào)用子序列的宏CV_R
24、EAD_SEQ_ELEM,在反向閱讀的情況下,調(diào)用宏CV_REV_READ_SEQ_ELEM.。這兩個(gè)宏將序列元素放入到read_elem并且移動(dòng)reading 指針指向下一個(gè)元素。獲得接下來(lái)的元素的一個(gè)可替代的方式是使用宏CV_NEXT_SEQ_ELEM(elem_size,reader),如何序列元素很多,它是首選的。在這種情況下,我們使用CvQuadEdge2D *edge=(CvQuadEge2D*)(reader.ptr)來(lái)訪問(wèn)邊緣,這僅是一個(gè)從一個(gè)reader指針到CvQuadEdge2D指針的一個(gè)強(qiáng)制轉(zhuǎn)換。宏CV_IS_SET_ELEM僅檢查指定的邊是否被占用。給定一個(gè)邊,我們需
25、要調(diào)用cvSubdiv2DEdgeOrg函數(shù)來(lái)獲得該邊的源點(diǎn)。為了遍歷一個(gè)三角形,我們重復(fù)的調(diào)用cvSubdiv2DEdge并且傳遞三角形方向,例如它可以是AROUND_LEFT或者CV_NEXT_AROUND_RIGHT.三角紋理變形(映射)Triangle texture warping既然我們能夠 迭代的訪問(wèn)一個(gè)劃分的三角形,我們能夠?qū)⒁粋€(gè)原始標(biāo)記的圖像變換到一個(gè)產(chǎn)生的扭曲的圖像。這對(duì)于將原始形狀的紋理映射到扭曲的形狀很有用。下面的代碼將引導(dǎo)這個(gè)過(guò)程:void warpTextureFromTriangle(Point2f srcTri3, Mat originalImage, Poin
26、t2f dstTri3, Mat warp_final)Mat warp_mat(2, 3, CV_32FC1);/仿射變換矩陣Mat warp_dst, warp_mask;CvPoint trianglePoints3;trianglePoints0 = dstTri0;trianglePoints1 = dstTri1;trianglePoints2 = dstTri2;warp_dst = Mat:zeros(originalImage.rows, originalImage.cols, /存儲(chǔ)仿射變換后圖像originalImage.type();warp_mask = Mat:ze
27、ros(originalImage.rows, originalImage.cols, originalImage.type();/ Get the Affine Transform /獲取仿射變換warp_mat = getAffineTransform(srcTri, dstTri);/ Apply the Affine Transform to the src image /對(duì)圖像應(yīng)用仿射變化warpAffine(originalImage, warp_dst, warp_mat, warp_dst.size();cvFillConvexPoly(new IplImage(warp_ma
28、sk), trianglePoints, 3, CV_RGB(255,255,255), CV_AA, 0); /new IplImage是一個(gè)指針指向warp_maskwarp_dst.copyTo(warp_final, warp_mask);/效果參考下圖(除三角剖分映射的地方,其他均為白色)。先前的代碼假定我們有了三角形頂點(diǎn),并且存儲(chǔ) 在srcTri數(shù)組中以及目的點(diǎn)存儲(chǔ)在dstTri數(shù)組中。23的warp_mat矩陣用來(lái)獲取從源三角形到目的三角形的仿射變換。更多的信息可以O(shè)penCV的cvGetAffineTransform文獻(xiàn)中引用。函數(shù)cvGetAffineTransform計(jì)算一
29、個(gè)仿射變換的矩陣,如下:在前面的等式中,目的(i)等于(xi,yi),源(i)等于(xi,yi),i等于0,1,2.獲得仿射矩陣之后,我們可以應(yīng)用仿射變換到源圖像。這通過(guò)warpAffine函數(shù)實(shí)現(xiàn)。因?yàn)槲覀儾幌裨谡麄€(gè)圖像上進(jìn)行我們想關(guān)注我們的三角形掩碼可以用來(lái)完成這個(gè)任務(wù)。這樣,最后一行代碼僅拷貝帶有剛才創(chuàng)建的掩碼的源圖像上的三角形,掩碼通過(guò)函數(shù)cvFillConvexPoly調(diào)用填充。下面的截圖展示了應(yīng)用這個(gè)過(guò)程到注釋圖像中的每一個(gè)三角形的結(jié)果。注意這些三角形映射到匹配的框架,他們的臉朝向視者。這個(gè)過(guò)程用于創(chuàng)建AAM的統(tǒng)計(jì)紋理。前面的截圖展示了將左圖像中所有的三角形映射到了一個(gè)均值參考框架
30、。模型實(shí)例化使用主動(dòng)表觀模型Model Instantiation-playing with the Active Appearance Model AAM有趣的一面是它們能夠簡(jiǎn)單地插值我們訓(xùn)練圖像的模型。通過(guò)一對(duì)形狀或者模型參數(shù)的調(diào)整,我們可以習(xí)慣于他們表現(xiàn)出的驚人的力量。當(dāng)我們改變形狀參數(shù)時(shí),根據(jù)訓(xùn)練形狀數(shù)據(jù)我們的變化方向發(fā)生了變化。另一方面,當(dāng)表觀參數(shù)修改時(shí),基于形狀的紋理也發(fā)生修改。我們的扭曲變換將每一個(gè)三角形從基本形狀變換到修改的目的形狀,因?yàn)槲覀兛梢栽谝粋€(gè)張開(kāi)的嘴上組合一個(gè)關(guān)閉的嘴,將像下面截圖展示的那樣:前面的截圖展示了一個(gè)組合的閉合嘴,它是通過(guò)另外一個(gè)圖像上的主動(dòng)表觀形狀的實(shí)例
31、化獲得的。它表明我們是怎樣組合一個(gè)微笑的嘴和一個(gè)欽佩的臉,推斷訓(xùn)練的圖像。前面的截圖是通過(guò)僅改變形狀的三個(gè)參數(shù)和紋理的3個(gè)參數(shù)獲得的,這是AAM的目標(biāo)。對(duì)于想使用AAM的讀者,一個(gè)簡(jiǎn)單的應(yīng)用的開(kāi)發(fā)可以在/訪問(wèn)的到。實(shí)例化一個(gè)模型僅是簡(jiǎn)單的滑動(dòng)等式參數(shù)的問(wèn)題,就像Getting the feel of PCA部分定義的那樣。你應(yīng)當(dāng)注意AAM搜索和匹配依賴這種靈活性為給定的模型捕獲到幀找到最佳匹配,我們的模型的來(lái)至于訓(xùn)練集中的不同位置。我們將在接下來(lái)的部分看到。AAM搜索和匹配AAM search and fitting 帶著新的組合的形狀和紋理,我們發(fā)
32、現(xiàn)了一個(gè)很好的方式來(lái)描述人臉不僅在形狀上而且在表觀上是怎樣變化的?,F(xiàn)在我們想找一組p形狀參數(shù)和lambda個(gè)表觀參數(shù),能將我們的模型盡可能的接近于一個(gè)給定的輸入圖像I(x)。自然地,我們可以在I(x)的坐標(biāo)框架內(nèi)計(jì)算我們的實(shí)例化模型和給定輸入圖像之間的誤差,或者將這些點(diǎn)投影到基本表觀并且計(jì)算那里的差異。我們將使用后面的這個(gè)方法。這樣,我們想最小化下面的函數(shù):在上面的等式中,S0表示像素集x等于(x,y)T,(x,y)T位于AAM基本網(wǎng)格的內(nèi)部。A0x是我們基本網(wǎng)格的紋理。Ai(x)是來(lái)至PCA的表觀圖像,W(x:p)是像素從輸入圖像投影到基本網(wǎng)格框架的變換。通過(guò)多年的研究,提出了幾個(gè)能夠?qū)崿F(xiàn)這
33、個(gè)最小化的方法。第一個(gè)思想是使用一個(gè)增加的方法,其中 pi和i作為誤差圖像的線性函數(shù)來(lái)計(jì)算。然后,形狀參數(shù)p和表觀在第i次迭代中作為 pi pi+ pi和 i i+ i來(lái)更新。盡管收斂有時(shí)發(fā)生,delta不總是依賴于當(dāng)前的參數(shù),并且這可能導(dǎo)致發(fā)散。另外一個(gè)方法非常慢,它是基于梯度下降法的研究,因此尋找另外一個(gè)收斂的方法被找到。替代更新參數(shù),可以更新整體變換。這樣,Ian Mathews 和Simon Baker在他們著名的論文稱為:再去訪問(wèn)主動(dòng)表觀模型(Active Appeance Models Revisited)中提出。更多的細(xì)節(jié)可以在這篇論文中找到,它給匹配的一個(gè)重要的貢獻(xiàn)是它將大部分
34、的密集型計(jì)算帶到了預(yù)計(jì)算步驟,就像下面的截圖所看到的那樣:注意更新發(fā)生在組合步驟(9)(看上面的截圖)。等式(40)和(41)來(lái)至論文,可以在下面的截圖看到:盡管算法僅提到從一個(gè)位置靠近最后一個(gè)位置大部分收斂的很好。當(dāng)在旋轉(zhuǎn)、平移和尺度上存在一個(gè)大的差異時(shí),這可能不適應(yīng)于這樣的情況。我們可以通過(guò)一個(gè)全局的2D相似變換的參數(shù)化將更多的信息帶到收斂。這是論文中的等式42,展示如下:在上面的等式中,這四個(gè)參數(shù)q=(a,b,tx,ty)T有下面的闡述。第一對(duì)(a,b)與尺度k和旋轉(zhuǎn) 相關(guān),a等于kcos(theta)-1,b=ksin(theta)。第二對(duì)(tx,ty)是x,y上的平移。就像在再次訪問(wèn)
35、主動(dòng)形狀模型文章中提到的那樣。帶有更多的數(shù)學(xué)變換,最終我們可以使用前面的算法來(lái)找到和一個(gè)全局2D變換最匹配的圖像。因?yàn)樽冃危╳arp)組合算法有幾個(gè)性能優(yōu)點(diǎn),我們將使用在AAM Revisited論文中描述的那個(gè),反向組合投影算法(inverse compositional project-out algorithm)。記住在這個(gè)方法中,匹配時(shí)表觀的效果可以預(yù)先處理,或者投射出提升AAM匹配性能。下面的截圖展示了使用反向組合投射AAM匹配算法得到的來(lái)至MUCT數(shù)據(jù)庫(kù)不同圖像的收斂。先前的截圖現(xiàn)實(shí)了成功的收斂臉的外部AAM訓(xùn)練集使用了inverse compositional project-o
36、ut AAM fitting algorithm。POSIT姿態(tài)我們找到我們標(biāo)記點(diǎn)的2D位置之后,我們可以使用POSIT獲得我們模型的3D姿態(tài)。一個(gè)3D對(duì)象的姿態(tài)P定義為33的旋轉(zhuǎn)矩陣R和3D平移向量T,因此P等于R|T。注釋:這節(jié)大部分是基于Javier Barandiaran編寫的OpenCV POSIT手冊(cè)。像名字暗示的那樣,在若干次迭代中,POSTI使用“姿態(tài)來(lái)至于正交和尺度”算法,因此,它是POS和迭代的縮寫。它假設(shè)我們可以在圖像中檢測(cè)和匹配四個(gè)或者更多的目標(biāo)的非共面特征點(diǎn)并且我們知道這個(gè)目標(biāo)上的相關(guān)幾何。該算法的主要思想是我們可以找到一個(gè)關(guān)于目標(biāo)姿態(tài)的好的近,這假定所有模型點(diǎn)在同一
37、個(gè)平面內(nèi)。因?yàn)槿绻覀儽容^相機(jī)到一個(gè)人臉的距離,這些點(diǎn)的深度將非常不同。初始化姿態(tài)獲得之后,通過(guò)解決一個(gè)線性系統(tǒng)找到目標(biāo)的旋轉(zhuǎn)矩陣和平移向量。然而,近似的估計(jì)迭代地用來(lái)更好地計(jì)算特征點(diǎn)的尺度化正交投影,跟隨著這些投影(而不是原始點(diǎn))的POS應(yīng)用。為了獲得更多的信息,我們可以參考: the paper by DeMenton, Model-Based Object Pose in 25 Lines of Code.投入到POSITDiving into POSIT為了使POSIT工作,我們至少需要4個(gè)非共面模型3D點(diǎn)和它們各自的2D圖像中的匹配。我們?cè)黾右粋€(gè)結(jié)束標(biāo)準(zhǔn),因?yàn)镻OSIT是一個(gè)迭代算法
38、一般地它是迭代的次數(shù)或者一個(gè)距離參數(shù)。然后,我們調(diào)用cvPOSIT函數(shù),這個(gè)函數(shù)產(chǎn)生旋轉(zhuǎn)矩陣和平移矢量。作為一個(gè)例子,我們將跟隨著JavierBrandianran編寫的手冊(cè),它用POSIT來(lái)獲得一個(gè)立方體的姿態(tài)。模型用4個(gè)點(diǎn)創(chuàng)建。用下面的代碼初始化:float cubeSize = 10.0;std:vector modelPoints;modelPoints.push_back(cvPoint3D32f(0.0f, 0.0f, 0.0f);modelPoints.push_back(cvPoint3D32f(0.0f, 0.0f, cubeSize);modelPoints.push_ba
39、ck(cvPoint3D32f(cubeSize, 0.0f, 0.0f);modelPoints.push_back(cvPoint3D32f(0.0f, cubeSize, 0.0f);CvPOSITObject *positObject = cvCreatePOSITObject( &modelPoints0, static_cast(modelPoints.size() );注意模型本身用cvCreatePOSITObject方法創(chuàng)建,它返回一個(gè)將在cvPOSIT函數(shù)中使用的一個(gè)CvPOSITObject方法。注意,姿態(tài)將參考第一個(gè)模型點(diǎn)來(lái)計(jì)算,這使得將它放在原點(diǎn)是個(gè)好的主意。然而,我
40、們需要將2D圖像點(diǎn)放入到另外一個(gè)vector中。記住,這些點(diǎn)必須以同樣的順序放置在數(shù)組中,模型的點(diǎn)插入到這個(gè)數(shù)組中。這樣,第i個(gè)2D圖像點(diǎn)匹配第i個(gè)3D模型點(diǎn)。這里,一個(gè)問(wèn)題是2D圖像點(diǎn)的原點(diǎn)位于圖像的中心,這可能需要你平移它們。你可以插入下面的2D圖像點(diǎn)(當(dāng)然,它們將根據(jù)用戶的匹配變化)。std:vector srcImagePoints;srcImagePoints.push_back( cvPoint2D32f( -48, -224 ) );srcImagePoints.push_back( cvPoint2D32f( -287, -174 ) );srcImagePoints.push
41、_back( cvPoint2D32f( 132, -153 ) );srcImagePoints.push_back( cvPoint2D32f( -52, 149 ) );現(xiàn)在,你僅需要為矩陣分配內(nèi)存和創(chuàng)建終止標(biāo)準(zhǔn),接著調(diào)用cvPOSIT,就像下面的代碼片段展示的那樣:/Estimate the poseCvMatr32f rotation_matrix = new float9;CvVect32f translation_vector = new float3; CvTermCriteria criteria = cvTermCriteria(CV_TERMCRIT_EPS | CV_T
42、ERMCRIT_ITER, 100, 1.0e-4f);cvPOSIT( positObject, &srcImagePoints0, FOCAL_LENGTH, criteria, rotation_matrix, translation_vector );迭代完成之后,cvPOSIT將結(jié)果存儲(chǔ)在rotation_matrix和translation_vector.下面的截圖展示了帶有白色圓圈的scrImgePoints,以及一個(gè)坐標(biāo)軸來(lái)表明旋轉(zhuǎn)和平移的結(jié)果。參考前面的截圖,讓我們看一下輸入的點(diǎn)和運(yùn)行POSIT算法的結(jié)果:1、 白色圓圈表示輸入點(diǎn),同時(shí)坐標(biāo)軸表示結(jié)果模型的姿態(tài)。2、 當(dāng)通過(guò)一
43、般標(biāo)定過(guò)程獲得焦距時(shí),請(qǐng)確保你的相機(jī)使用了焦距。你可能想檢查一下標(biāo)定的過(guò)程可以訪問(wèn):in the Camera calibrationsection in Chapter 2, Markerbased Augmented Reality on iPhone or iPad. POSIT當(dāng)前的實(shí)現(xiàn)僅允許正方形的像素,因?yàn)閷?duì)于焦距的長(zhǎng)度沒(méi)有余地在x和y軸上。3、 期望的旋轉(zhuǎn)矩陣為下面的格式:4、 平移矢量為下面的格式:POSIT和頭部模型為了使用POSIT作為姿態(tài)估計(jì)的一個(gè)工具,我們將使用一個(gè)3D頭部模型。There is one available from the Institute of S
44、ystems and Robotics of the University of Coimbra and can be found at http:/aifi.isr.uc.pt/Downloads/OpenGL/glAnthropometric3DModel.cpp注意這個(gè)模型可以在它描述的地方獲得:float Model3D583= -7.,0.,0., .這個(gè)模型可以通過(guò)下面的截圖看到:先前的截圖展示了POSIT可利用的一個(gè)58個(gè)點(diǎn)的3D頭部模型。為了使POSIT工作,相對(duì)于3D頭部模型的點(diǎn)必須相應(yīng)地匹配。注意,至少需要4個(gè)非共面的點(diǎn)和它們相應(yīng)的2D投影來(lái)使POSIT工作,因此,它們必須
45、作為參數(shù)傳遞,大致上和Diving into POSIT部分描述的那樣。注意這個(gè)算法在匹配點(diǎn)的數(shù)量方面是線性的。下面的截圖展示了匹配是怎么樣完成的:先前的截圖展示了一個(gè)3D頭部模型和一個(gè)AAM網(wǎng)格的正確的匹配點(diǎn)。從網(wǎng)絡(luò)攝像機(jī)或者視頻文件跟蹤既然我們已經(jīng)收集了所有的工具來(lái)獲得6個(gè)自由度的人臉跟蹤。我們可以應(yīng)用它到一個(gè)相機(jī)流或者視頻文件。OpenCV提供了VideoCapture類,這個(gè)類可以用下面的方式使用(獲取跟到的信息,可以看:see the Accessing the webcamsection in Chapter 1, Cartoonifier and Skin Changer for
46、 Android)#include cv.h#include highgui.husing namespace cv;int main(int, char*)VideoCapture cap(0);/ opens the default camera, could use a /打開(kāi)默認(rèn)相機(jī),可以使用一個(gè)視頻文件路徑替代/ video file path instead if(!cap.isOpened() / check if we succeeded /檢查是否成功return -1;AAM aam = loadPreviouslyTrainedAAM(); /導(dǎo)入先前訓(xùn)練的AAMHead
47、Model headModel = load3DHeadModel();/導(dǎo)入3D頭部模型Mapping mapping = mapAAMLandmarksToHeadModel();/將AAM投影到頭部模型Pose2D pose = detectFacePosition();/檢測(cè)人臉的位置while(1)Mat frame;cap frame; / get a new frame from cameraPose2D new2DPose = performAAMSearch(pose, aam);Pose3D new3DPose = applyPOSIT(new2DPose, headMod
48、el, mapping);if(waitKey(30) = 0) break;/ the camera will be deinitialized automatically in VideoCapture / destructorreturn 0;算法是這樣運(yùn)作的。一個(gè)視頻捕捉通過(guò)VideoCapture(0)來(lái)初始化,因此將使用默認(rèn)的相機(jī)。既然我們使得視頻捕捉工作了,同樣地我們需要我們訓(xùn)練的主動(dòng)表觀模型,這在偽代碼load PreviouslyTrainedAAM mapping中實(shí)現(xiàn)。我們同樣為POIST算法導(dǎo)入3D頭部模型并且導(dǎo)入存儲(chǔ)在映射變量中的標(biāo)記點(diǎn)到3D頭部點(diǎn)的映射。我們需要的所
49、有事情導(dǎo)入之后,我們將從一個(gè)已知的姿態(tài)初始化算法,這是一個(gè)已知的3D姿態(tài),已知的旋轉(zhuǎn)和已知的一組AAM參數(shù)。這將通過(guò)OpenCV詳細(xì)記載的Haar特征分類人臉檢測(cè)器自動(dòng)的完成(更多的細(xì)節(jié)在第六章非剛性人臉跟蹤中的人臉檢測(cè)器部分,或者OpenCV的級(jí)聯(lián)分類器文獻(xiàn)),或者我們可能手動(dòng)地從先前標(biāo)記的框架中初始化一個(gè)姿態(tài)。同樣可以使用一個(gè)brute-force方法,它將為每一個(gè)矩形運(yùn)行一個(gè)AAM匹配,因?yàn)閮H在第一幀的搜索中它很慢。注意通過(guò)初始化,我們想要通過(guò)它們的參數(shù)找到AAM的2D標(biāo)記。當(dāng)所有的事情導(dǎo)入了之后,我們可以通過(guò)while 循環(huán)限定的主循環(huán)來(lái)進(jìn)行迭代。在這個(gè)循環(huán)中,我們首先訪問(wèn)下一個(gè)獲取的
50、視頻幀,然后我們運(yùn)行一個(gè)主動(dòng)表觀模型,以便我們可以在下一幀圖像中找到標(biāo)記。既然在這一步,當(dāng)前位置非常重要,我們將它作為一個(gè)參數(shù)傳遞給偽代碼函數(shù)performAASearch(pose,aam)。如果我們找到了當(dāng)前姿態(tài),它通過(guò)誤差圖像收斂傳遞了一個(gè)信號(hào),我們將獲取下一個(gè)標(biāo)記位置,因此我們可以將它們提供給POSIT。這發(fā)生在下面的命令行:applyPOSIT(new2DPose,headModel,mapping),這里新的2D姿態(tài)作為一個(gè)參數(shù)傳遞,同樣地像我們先前導(dǎo)入的headModel和mapping。之后,我們可以在獲得姿態(tài)中渲染任何3D模型,如一個(gè)坐標(biāo)系軸或者一個(gè)增強(qiáng)現(xiàn)實(shí)的模型。當(dāng)我們有了
51、標(biāo)記,通過(guò)模型的參數(shù)化可以獲得更多有趣的效果,例如張開(kāi)嘴或者改變眉毛的位置??偨Y(jié):在這一章,我們已經(jīng)討論了主動(dòng)表觀模型是怎么樣和POSIT組合來(lái)獲得一個(gè)3D頭部姿態(tài)。關(guān)于如何創(chuàng)建,訓(xùn)練和操作AAM的概述已經(jīng)給出,讀者可以使用這些背景到任何領(lǐng)域,例如醫(yī)療,圖像處理,或者企業(yè)。進(jìn)一步處理AAMs,我們熟悉了Delaunay三角剖分并且學(xué)習(xí)了如何使用這樣有趣的結(jié)構(gòu)作為一個(gè)三角剖分的網(wǎng)格。我們同樣展示了如何OpenCV函數(shù)在三角形上執(zhí)行紋理映射。另外一個(gè)感興趣的主題是AMM匹配的方法。盡管只描述了反向組合投影算法,我們可以簡(jiǎn)單的通過(guò)使用它的輸出來(lái)獲得多年研究的結(jié)果。學(xué)習(xí)了充足的理論和AAM的實(shí)踐之后,我們投入到POSIT的細(xì)節(jié)來(lái)結(jié)合2D測(cè)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 勞務(wù)分包企業(yè)合同范本
- 華萊士加盟合同范例
- 勞務(wù)合同范本遷戶口
- 單位食堂承攬合同范本
- 個(gè)人農(nóng)業(yè)養(yǎng)殖合同范本
- 加盟合同范本李慶亮
- 出售公司房屋合同范本
- 人壽第三方代理合同范本
- 勞動(dòng)用工合同范本范本
- 企業(yè)策劃標(biāo)準(zhǔn)合同范本
- 高新技術(shù)企業(yè)認(rèn)定申請(qǐng)書樣例與說(shuō)明
- 數(shù)據(jù)結(jié)構(gòu)英文教學(xué)課件:chapter6 Tree
- 高壓氧科工作總結(jié)高壓氧科個(gè)人年終總結(jié).doc
- 《政治學(xué)概論》教學(xué)大綱
- 橋梁缺陷與預(yù)防
- 食品生物化學(xué)習(xí)題謝達(dá)平(動(dòng)態(tài))
- 新蘇教版小學(xué)科學(xué)三年級(jí)下冊(cè)全冊(cè)教案(2022年春修訂)
- 保安員工入職登記表
- 睿達(dá)RDCAM激光雕刻切割軟件V5.0操作說(shuō)明書
- 機(jī)械設(shè)計(jì)基礎(chǔ)平面連桿機(jī)構(gòu)課件
- 人力資源部經(jīng)理崗位說(shuō)明書
評(píng)論
0/150
提交評(píng)論