創新工場王嘉平開講:low-level的計算機視覺

weixin_34319999發表於2018-01-09
本文來自AI新媒體量子位(QbitAI)

640?wx_fmt=png&wxfrom=5&wx_lazy=1
近日,在DeeCamp創新工場深度學習訓練營期間,創新工場AI工程院副院長王嘉平開講《low-level的計算機視覺》一課。

量子位把課程全部內容整理如下:

今天要和大家一起聊一聊的是low-level的computer vision。

當下這個時代,high-level vision已經有了長足的進展,在包括face recognition, 自動駕駛等的領域提到的次數也越來越多。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

那我為什麼要講low-level vision呢?我們知道在high-level vision task的中,machine learning很強大,只要給它一些資料,足夠的資料,它就可以學出來。但我們更需要關心一下資料是怎麼來的,資料本身有些什麼樣的問題。這些都和low-level vision有關。如果瞭解了low-level vision,做 high-level vision的時候有非常大的幫助。

我舉一個例子。

很久以前在做OCR的時候, 我們要在image中把影像識別出來,而machine learning task拿到的資料不是無限的,只cover了一部分,這當中隱含了一些不想要的資料的變化,比如OCR上的光照的變化,漸變和一些distortion,而且跟這個字具體是哪個字無關。

但是如果你不去掉這些變化,直接往machine learning model裡面丟,如果資料足夠的多,當然model可以把這些無關的變化和有關的變化分開,但事實上沒有那麼多的資料。如果你學了low-level vision,你就可以想是否能預先把這些variation去掉,再送到machine learning 裡面去,會使後面的machine learning更高效,依賴於更少的資料。

CV涉及很多方面,從訊號的獲取,處理分析到最後的understanding,和很多學科都有關係,像machine learning,optics,computer graphics,並這關乎我們對於真實世界的理解,但由於感測器的限制,我們這樣的理解通常來自二維或者一維的投影,而不是完整的三維的資料。

所以這件事情基本上是整個CV,尤其是3D CV最大的挑戰。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

首先對於CV,計算機看到了什麼?

對於這張圖來說,雖然已經是三維空間的投影,但也不是三維空間本身,我們只看到了一個側面。很多物體被遮擋了,很多資訊被丟失了。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

對一張影像來講,我們量化了每個方向上接受的光子的通量,並且離散化,拿到了一個包含很多值的資料集。每個值代表了感測器上一小塊面積所接收到的單位時間裡的光通量。光強越大,值就越大。這就是計算機看到的影像。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

我們先講一個pixel上的value是怎麼來的。要提到的是,它上面可能是luminance,也可能是luminance per channel。我們現在看到RGB,也就是3個channel。

channel代表顏色。而顏色沒有單位,因為顏色不是物理量,是主觀的量,本質上是我們的感測器也就是眼睛看到不同的光譜時在感光器上激發的量,真正的背後的物理量是光譜,也就是在不同頻段上能量的分佈。

人之所以感覺到顏色,是人類視覺系統用這三個積函式去積分了所接受的光譜,最後形成了三個感光細胞所拿到的係數,然後對映到RGB的色彩空間。

色彩既然是主觀的,不同的生物也不一樣,這和生物在整個生態系統所處的位置是有關係的,是生物進化導致的。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

顏色不是絕對的。

除了直接去觀察光源,大部分顏色是光源的顏色和物體表面所反射的係數乘積得到的顏色,是疊加反射係數的顏色最終看到的。這就意味著我們看到的不是物體本真的反射光譜的分佈,而是它跟光源互動的結果。所以在現實中不同的物體反射出的差別很大。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

描述各種反射特性的物理量叫BRDF。

首先是反射係數,多少量的光強達到這個表面上有多少量的光強被反射出去了,並且這個光強和入射角度和出射角度都是有關係的,進去一個球面的角度,出去一個球面的角度,所以總共它是一個四維的函式。

這個在圖形學裡面被非常heavy的study。因為我們要在計算機裡重現真實世界中物體的外觀,這個函式就決定了這個物體的外觀是什麼樣子的。我們做一個matching,做stereo,從不同的角度看物體,試圖去找到對應的點。

這裡的挑戰是假設這個函式是一個常量,就意味著對這個特定的點,不論從哪個角度,顏色一樣。真實世界不是這樣的。

真實的世界中,這個BRDF並不是一個常量。即使是同一個點不同視角去看顏色也是不一樣的。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

早年的vision裡面,會假設一個所謂的lambertian surface。

反射是由於物體表面粗糙的微元面導致的,光打上去後會朝不同的方向去發散反射。假設光強在各個方向的反射是均勻的,這個就叫diffuse reflection。

粉筆和石膏就和這個十分接近。diffuse reflection意味著什麼呢?早年的stereo演算法都假設對特定的點從不同角度去看都是一樣的,我們就可以用不同角度圖片上的feature點去做對應,推演其三維空間的位置。但是實際問題是specular reflection。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

光源反射不均勻,通常會在鏡面方向上多一點,然後形成沿著鏡面光源散射的specular peak。

如果這個specular peak很瘦,就會形成一個很亮的點。極限情況下它可能是一個衝擊函式,這個時候物體看起來就像一面鏡子。有點時候又會寬一點,比如啞光的材料。

這個會帶來很多困難。因為multiple view的時候顏色會發生變化,尤其specular很強的時候,就會導致stereo,matching等很難做,很多演算法也會受到影響。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

這是一個簡單的磨皮演算法。大概三四行程式碼就可以實現。

大家怎麼看一個磨皮演算法的效果?就看在去掉臉上皺紋的同時,眉毛和頭髮有沒有留下。磨皮演算法本質上要把空間中一些細節去掉,但對於計算機來講,很難區別紋路,是皺紋還是毛髮。

這裡的兩張圖,左邊的圖裡把所看到的亮度的變化的G和B去掉,只用R來構造亮度的變化。當然只把亮度替換掉,把顏色留下。另外一張則把G留下。

由於不同波長的光在皮膚裡散射的不同,散射強的紅色就會把皮膚的褶皺給blur掉,但毛髮不受影響。綠色就基本沒有做什麼blur,留下了皮膚上各種粗糙的東西。

有種說法是尼康相機適合拍人像,原因是什麼呢?人類構造影像有三條三原色的曲線。相機為了接近人類的視覺,構造出人類最後可以看到的影像,同樣也有類似的三條曲線,尼康的感測器裡構造RGB系統時分量系統往綠色和藍色的分量少一點。當系統把很高維的分量投射到三維裡面去的時候,背後的光路是不一樣的,雖然投影后顏色是一樣的。佳能往高能量的光譜多一些。因此尼康拍人像的時候,細節更多來自紅色的通道,所以皮膚就會看起來很好。當然這個差異不是非常的大。

說完光譜的事情,我們現在假設所有的事情在一個通道上發生。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

對於現有的大部分感測器,光進來後經過一系列的處理最終變成影像上面pixel上的value,這裡有幾個步驟。

首先經過一個鏡頭並處理後,有一個exposure。因為感測器不是真的拿一個snapshot,其實是積分了一段時間才能測量到光的強度。然後經過模式轉換器,把光通量模擬量轉換成一個資料量。最後還有一些post-processing。

為了儘可能多得看清細節,亮部暗部都要有一些。但我們發現最終的影像有些部分飽和掉了看不清楚了。

那麼在vision的採集系統裡都有哪些坑?

640?wx_fmt=png&wxfrom=5&wx_lazy=1

首先,過鏡頭的時候會濾掉一部分波長的光,因為大部分系統不是為vision understanding設計的,是為拍照設計的。為了得到更好的成像的質量就會濾掉一些對於構造圖片沒有用的光。紫光一般被反射出去了。

這是一個増透膜,使得更多的光進入鏡頭,可以提高照片質量。

大部分CCD和相機其實對紅外光都是很敏感的,我們可以拿遙控器對著手機看是很亮的,所以幾乎所有的鏡頭都會對紅外光有一個過濾。如果不過濾,幾乎是一片白。

這部分做了一個filter mask,把我們不想看的紫外紅外幹掉。剩下可見光透過鏡頭。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

接著是曝光。

最後,sensor上面讀到的資料等於曝光時間乘以光通量。因為感測器的敏感度是有限的,進光量很小的時候為了把照片拍出來就需要比較長的曝光時間,那麼為了完整地獲取影像的一幀,就需要幀率不能超過曝光時間分之一。

自動獲取影像模組把曝光時間調大,一旦調大到幀率分之一還大,幀率就會降下來。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

這裡的第一個問題是rolling shutter。

大家看到這裡直升機的螺旋槳拍下來不是直的。因為當我們的成像的時候,影像上的畫素不是在同時獲得的,最上面的pixel可能是0.0001秒,第二行是0.0002秒。整張影像是掃描獲得的,而物體運動足夠快的時候,不同行獲得的資訊不一致,但掃描的過程是連續的,所以最後的圖片就變成這樣一個連續的扭曲了。

第二個是motion blur。

同樣拍運動物體。為了測量不同pixel上的進光量,就需要一個一段時間的積分。如果在那段很短的時間內有很多的snapshot,我們把它們疊加到一起。如果物體運動得夠快,哪怕10毫秒可以造成影像很大的不同。在exposure的瞬間,物體已經跑了一段距離了,那麼最後拿到的是積分的結果。比如識別路牌,motion blur 對此就很不利。

為了減少這兩種問題,最好的方法是減少曝光時間,這意味著在成像過程中,會有更少的光子來。假設感測器的敏感度不變。不同的照片在不同的iso上拍的。

由於成像係數在前面計算,不涉及量化的問題。如果把曝光減少,不調iso,影像就會變暗。而當曝光時間很小,猛調感測器係數時,就會出現噪音。因為感測器本來就有熱噪聲。所以曝光時間是一個矛盾的事情,太大了會blur,太小了有噪聲。

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1

我們再說到CCD上面,感測器上會發生兩件事。

第一是飽和。光是線性的,為了拍出暗部,把亮的部分砍掉。意味著我們可以確定亮度範圍,把超出的部分砍掉,然後去做量化。

這裡會有幾個問題。

我們為了拿到暗部的細節,就會丟掉亮部的細節。如果為了留下亮部的細節,要使整張圖片都沒有飽和。亮度除以一萬倍,最亮才能fit到量化空間裡,但暗部的細節就沒有了。

本質上說圖片量化精度不夠,而沒有那麼多量化點。我們會人為選擇的量化範圍。要不留下亮度的細節,要不留下暗部的。線性量化的時候,有時候量化精度不夠,比如gif影像通常量化的層級不夠。我們有時可以過渡。

這些都是因為我們的感測器和處理電路的限制。一般的影像是8位。有些人要拿raw,就意味著拿CCD原始的東西。有的CCD裡面的raw是10個bit或者12個bit一個變數,這樣量化要好些。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

最後是對模式轉換器做最後的變化。

前面全部是線性變化。這一步是非線性的變化,比如白平衡,色彩的矯正,伽瑪矯正。

這裡面的伽瑪通常是值的1.2次方或1.5次方,這個可以近似人眼對光強的反應:人眼的反應不是線性的,這意味著暗部的量化精度高於亮部。

大部分手機或單反拿到的影像,引入非線性意味著什麼呢?

比如我們要做人臉識別,要去掉或者歸一化光照。假設pixel的值是線性。其實不是,都被處理過。真正做歸一化,先要做intensity recovery,通過拍攝不同亮度的照片反求這個函式。

因為是單調的函式,所以可以反過來算原來的線性空間的值。嚴格的做法是把值線性化,叫radiometric calibration。這是很多做vision task的第一步,但是很多被忽略了。

這個是可以保證我們拿到的pixel 是線性化之後的值。如果做線性變換,同比增加亮度,拿到的值不是2:1。線性化之後以後比例才能一致,才能準確地把光照條件帶來的variation去掉。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

在這個過程中我們可能會丟失很多資訊。尤其一個場景一旦飽和掉,不同pixel的值就都一樣了。

為了改善這件事,有個東西叫HDR,用最後從感測器拿到的影像重構光進入感測器前的場景。HDR其實是高動態範圍的影像,最大值和最小值的差距很大。

重構原理是因為拍照只留下設定的亮度範圍,只有這一段會被量化。那麼我們不斷改變曝光量,得到這個序列當中各個亮度範圍的細節,再把影像疊到一起。假設曝光時位置不變,那麼每個pixel就可以對起來。

我們把沒有飽和的畫素都選出來,做平均——這個首先要線上性化以後的值上做,把原來的值線性化——疊加完後拿到HDR影像,每個通道上的值都是一個浮點數,這樣就可以表達很大的動態範圍。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

然而我們的vision不是孤立地看一個,要看很多畫素。這些畫素有固定的結構和pattern,local feature在很多vision task裡面都要用到。

vision代表著影像中物體的piece,它雖然對物體的feature沒有理解,但它企圖去抓feature,這就是認定影像有一致的localization,不管在什麼位置,不管物體的位置和朝向,這個特定的feature點都跟著物體走。

feature找到後,要去encode這個feature,這個的對slam或stereo非常有用。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

我們再回歸邊緣檢測。邊緣檢測就是在影像中找到比較顯著的不連續的邊界。

在一維裡,用高斯函式的二階導卷積影像裡得到一些小波浪,這些小波浪會跟著影像走,這就是有localization特性。然而對一個pattern,要用兩個邊界去刻畫。我們不僅需要知道feature的位置,還要知道大小。

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1

這個函式的積分訊號和卷積和不是我想要的。訊號的size當和卷積和的kernel size差不多的時候,我們可以得到一個local minimum,這個點就是我們想要的。

這個點可以告訴我們feature的位置和大小。實際上遍歷各種不同大小的kernel去卷積,我們把它擴充到二維,就是一維函式沿軸旋轉一下。

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1

二維函式的本身是高斯和的二次求導。這個函式能夠在不同的寬度間拿到不同的值,使得不同的層互相比,到處找local minimum。最後拿到的資料中,每個圓圈的中心表示feature在哪裡,每個圓圈的大小表示feature有多大。

最關鍵的在於如果我把這個影像挪動,縮小,轉動,這些feature點也會跟著走。還有就是卷積的影像不只是一張。這些feature點是在不同的層上找的。因此找minimal不是在x,y上找,而是在x,y,z上找,然後投影。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

所以當我們很好的抓到這些位置之後,那麼首先要確定feature的位置,當feature點位置確定,要確定來自同一個函式,意味著我們要有一個尺度的衡量,我們不僅要知道一個feature點的大小和位置,我們還要在知道內容是什麼。

基於演算法找到feature後,用一個向量表示feature的內容,並抵禦縮放帶來的影響。這個feature裡物體的遠近出來的值差不多。x,y的移動已經歸一化。z軸也歸一化掉。

這個大量被使用在3D重構。本質思想是線條朝向記下來,計算梯度,用朝向刻畫內容,再用8個bit去刻畫。由於相機的影像是在不同的位置拍攝的,假如沒有運動的很快,就會是有重疊的,但拍的時候由於在動,不能簡單的疊加,要一對一對的解影像間的關係並拼起來。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

抓到feature點後就來找對應。對應裡可能會有很多的錯誤。求解的就是把所有的對應關係聯立上面大方程。每一個點做一個變換。這個變化是一個3×3的矩陣。只要超過9個方程,矩陣就可以求解。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

不正確的對應關係不能包含線上性系統裡面,不然結果會偏掉,假設正確的對應遠大於錯誤的,隨便找幾個對應關係。求解t,大部分正確但有偏差的。反向驗證對應關係,跟transformation是否一致,過於不一致就丟掉。

拍攝的時候光照的引數有點不一樣,細節一致,絕對亮度稍微有點不一樣。這就已經不是vision的事情了,是graphics的問題。有個泊松image的方法,梯度留下,絕對亮度丟掉。點與點之間的相對梯度關係連起來求泊松方程,解出image。這樣解完以後邊界就會消失了。

摒棄了絕對亮度,利用梯度的亮度重新生成。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

那麼三維空間的投影是怎麼發生的,成像是怎麼成的呢?

現實中每個物體對所有方向都在發光,放一個膠片或感測器上每一個點上的光照強度都來自於目標物體所有點的光強。要成像就要使得感測器上受到的光照來自物體的一個特定的點。

可以在光圈留一個很小的洞,唯一找到小孔反向求焦到真實世界的一個點。這就是小孔成像,也是最經典的pinhole camera的模型。

之所以能成像,要使得這一個點被照的內容,來自於儘量少的目標物體的點,小孔越小,光錐越小,點只貢獻到接收面上的很小一個點。小於一個畫素就可以成很清晰的像。

但當孔很小的時候,跑到感測器上的光很少,影像會很暗。理論上可以無限增長曝光時間,不斷積分,但並不實際。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

如果可以改變光的方向,聚到一個地方去,影像就可以清晰且不會太暗。於是人們發明了鏡頭,使點偏離光軸方向發生偏轉,形成聚焦。物距和焦距定了,像就定了。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

但感測器是平的,只能捕獲一個方向的畫素。實際物體時三維的,有一些點的最佳成像位置不同。有一些點會正好落在感測器上。這就是景深。

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1

只要在景深的範圍內成像就是比較清晰。其他點一定存在blur,只要小於一個畫素,就仍舊是清晰的。有時候因為距離的不同,真正的焦點會相差了一點點比如0.1毫米,這在影像上會造成多大範圍的模糊,還由光圈決定。

光圈小,blur的半徑會小一點,前後都清晰,但進光量會小。光圈大,鏡頭得大。意味著相機會大。而感測器大,單元面積大,接收更多的光子。如果焦距越短,張角越大,就像監控的廣角相機,一般大家不想要這種效果。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

視角變大就會引入徑向的畸變。徑向畸變一個是因為鏡頭的不完美,另一個是視場角,太大會形成突出的球面的效應。球面對映到平面總會有扭曲。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

畸變可以建模,扭回來。但是範圍就會奇怪,意味著就會裁掉一些東西,浪費一些畫素。

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1

為了更方便地去描述3D場景是怎麼樣被投射到二維的,機器視覺裡引入了一個叫齊次座標的東西。

因為使用除法後就不是線性系統,所以我們給它升維,這樣做的好處是升過維的向量可以和後面所有這些transformation可以formulate到一起去,變成一個線性的東西,最後成像的時候計算影像空間點的位置,在最後除一下就行。

影像距離越遠就會越接近光軸,那麼這個除法先不做,最後成像後再做,前面計算過程中就可以迴避非線性的問題。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

這些在數學中的公式就是perceptive matrix,四維投射成三維的矩陣乘法。真實世界中空間中有一個三維的點,有一個world座標到image座標的轉換過程。

比如世界座標系先建好,所有的點都定義進去,這時候相機可以放在特定位置,會有一個矩陣來描述,把世界座標系轉化為相機座標系,再乘perspective matrix,再相機座標系轉換到影像座標系。

這就是三維成像的基礎。

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1

這是處理大規模三維重建的方法。空間中的點拿到的影像乘了一個空間變換矩陣。現在相機和點的位置不知道,同樣一個物體被幾個相機拍了,聯立可以求得物體上的點和相機的位置。這個就是它的目標函式。

假設旋轉矩陣為已經知道了,translation和perspective都知道了,對應空間中的所有的feature點,點在影像上的正確位置是知道的。

要猜測求出空間中的位置,minimize這個錯誤。可以拿到相機的位置。這是非常大規模的,要優化幾百萬個點的位置,幾千張照片對應幾千個不同的相機的位置,還要同時優化相機的位置,最終做一起minimize。

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1

640?wx_fmt=png&wxfrom=5&wx_lazy=1

比如去網際網路上搜集某個景點遊客拍攝的圖片。做joint optimization。做local featurization會發現各有一堆的feature點,任何兩張feature點可以構造幾千個點,算出空間的位置。

如果聯立照片中三維點的位置就能重現一個點雲出來,用點雲刻畫三維場景中點的位置。但因為只是一個點雲,不是完整地構造幾何的表面。

同時對於那麼多影像,可以算出每一張是哪個位置拍的,google的街景就是這樣,這些點雲可以自己算出來是哪個位置拍的並精確到pixel level的位置。這樣就可以讓你很好的在照片與照片間遊走。就重建這個三維。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

回想一下,這裡用到的技術。每個點成像怎麼來的,根據這個定義local feature ,找到兩個點的對應關係並進行transformation。

所有的變化是在image space裡面變換的。這裡的不同位置是有視差的,求解不是影像空間的變換,是三維空間的變換。兩兩去做會發生最後的點雲和重構的點雲接不起來。因為傳遞會積累誤差。

如果距離很遠的話我們就要去重構一個大範圍的物體差別在於不同的影像重疊部分有多大,如果很大,那麼drafting也會很大。

那如果每次都重疊很小,transformation是通過鏈條積累起來的。這個就需要大量的feature點聯合。

總結

640?wx_fmt=png&wxfrom=5&wx_lazy=1

high-level vision task的時候,成像是一個imperfect的,而且有一個假設,不是我們想獲得什麼資料。同時獲得的資料是不是有問題的。告訴我們影像的變化是怎麼來的,是不是我們想要的。如果可以預先知道,提前去掉,使得資料的使用率大大提高。一旦high-level裡資料不夠,出現誤差,不能收斂,我們就需要去看看資料怎麼來的,回頭看看low-level vision怎麼來的。做machine learning等的時候,有時候去死調你的演算法引數不如獲得更多的資訊更好的資料有用,根據場景設計你的感測器系統,camera放在什麼位置,什麼光源。這個對high-level understanding能不能做好很重要。

問答環節:

1. 點雲生成後下一步是什麼呢?

基本的思想是兩個方面的資訊,告訴你每個點的位置直接連線,不一定可靠。每個點周圍有很多點。先構建一個graph,和周圍聯絡起來,但不能保證重構起來的是合法的流形。此時就有一堆幾何處理的演算法砍掉不正常的邊和點。

當影像足夠多的時候還可以知道每個點的法向量。

如果對同一個點,拍的照片能發現不同光照的亮度,根據拍攝時間和朝向估算光源的位置。在影像空間中重構法向量,不但給位置也給法向量。一旦有法向量就知道和graph哪些邊是不能連的,可以更好的構造面。

2. VR裡vision是否需要更多演算法去提高渲染質量?

不是vision的事情,更多是graphics的事情。

為了得到高質量渲染的影像,對物體的material要有很好的描述,比如BRDF能在計算機裡渲染出和照片一樣逼真的畫。

第二個是光照。除了photography上的應用,在computer graphics裡也很有意義。早期看到的graphics渲染的東西很artificial,很大問題是點光源化。

現實中不存在絕對的點光源,光還會間接照射這個物體,本身是全域性的光照計算照射系統。用HDR影像刻畫整個場景對它的光照,不是一個點去照射,而是一個球面積分,這樣渲染的質量會更接近真實的世界。VR現在機能沒有那麼強。

3. 三維空間的表面反射比較強部分,怎麼重建三維?

最基本的方法是找到不同視角對應的點,反算在空間的位置。但一旦對應關係不能被建立,就不能通過找對應重構。

這裡用photometric stereo,對物體打個側面的光。打很多側面的光,如果有物體表面反射一定假設,就能求出每個表面的法向量。只要改變光源的位置就能求出空間中每一個法向量是多少了。

有了法向量,積分就可以求出物體的曲面,位置。另外一套演算法是把場景弄成一片一片,每一片都可以求到一塊集合。先用法向量來做。

比如說有的物體表面反射光強和奇怪,不能找對應。那麼把圖片單獨做,把面上的法向量求出來,和視角無關。我們就可以回到原來的路,找對應,不是用RGB color找對應,而是用法向量構成的feature來做。

4. 機器學習中識別RGB ,如何用光度的方法如何把法向量丟進去學?

比如卷積神經網路,後面幾層都一樣。關鍵是前面幾層。現在前面的卷積的kernel,灰度影像除了5×5之外,只有一個5×5的卷積網路。如果後面是RGB後面就需要有三個。但因為向量是normalize過的單位向量,所以只要2個5×*5的就夠了。

我只關心每個pixel上有幾個維度,每個維度內容是什麼我不關心,只不過每個維度的value不一樣。本質還是刻畫影像的原本的特徵,但是一個是RGB的體現,一個是法向量的體現。比如一個RGB的kernel,每個點上面,除了RGB還有D,不做更好的優化,可以直接丟到CNN裡面,但是對前面卷積的5×5需要換成5×5來對應於每一個channel,這個實現就夠了。

有時候我們還是要care一下range不一樣。資料可以直接丟,也可以做一個歸一化,但歸一化可以讓全連線網路去學也不難,但是你開始不要直接丟進去學。前期已經知道模型的時期就不要丟進去學。要準備的資料也會變少,過程也會變簡單。

5. 法向量可以丟進去,我們在標法向量的時候很難標定條件怎麼辦?

640?wx_fmt=png&wxfrom=5&wx_lazy=1

法向量是算出來的,光源也是算出來的。假設光源遠,就可以放一個球,預先知道球的法向量,反算光源的位置。如果點光源近,就可以放四個球,預先知道四個球的法向量,通過光求的最亮點反求出方向和距離,就可以知道每個法向量是多少。

—— ——

本文作者:顏萌
原文釋出時間:2017-08-04

相關文章