1. 程式人生 > >真實場景的虛擬視點合成(View Synthsis)詳解

真實場景的虛擬視點合成(View Synthsis)詳解

  上一篇部落格中介紹了從拍攝影象到獲取視差圖以及深度圖的過程,現在開始介紹利用視差圖或者深度圖進行虛擬視點的合成。虛擬視點合成是指利用已知的參考相機拍攝的影象合成出參考相機之間的虛擬相機位置拍攝的影象,能夠獲取更多視角下的圖片,在VR中應用前景很大。

  視差圖可以轉換為深度圖,深度圖也可以轉換為視差圖。視差圖反映的是同一個三維空間點在左、右兩個相機上成像的差異,而深度圖能夠直接反映出三維空間點距離攝像機的距離,所以深度圖相較於視差圖在三維測量上更加直觀和方便。

  • 利用視差圖合成虛擬視點
  • 利用深度圖合成虛擬視點

一、利用視差圖合成虛擬視點

  由於視差圖反映的是三維空間點在左、右兩個相機上成像的差異,並且由於提前進行了立體校正,這種差異就反映在影象的同一行上。在立體匹配的SGBM演算法中就是以其中某一副為參考影象,在另一幅影象的同一行上搜索匹配點。因此在合成虛擬視點時也只需在同一行上平移虛擬攝像機位置即可。流程如下:

  (1). 假設視差圖中某一個畫素點的視差值為dmax,也就是說從左攝像機camL到右攝像機camR之間,該畫素點的視差值變化範圍為0~dmax。為了方便介紹我將其歸一化到alpha取值範圍為0~1。

  (2).那麼如果我要獲取alpha=0.5位置時候虛擬相機位置的影象呢,那麼此時該畫素點和左影象匹配點的座標差異就是0.5 * dmax,和右影象匹配點的座標差異也是0.5 * dmax;如果alpha=0.3,那麼此時該畫素點和左影象匹配點的座標差異就是0.3 * dmax,和右影象匹配點的座標差異也是0.7 * dmax;

  (3).根據上面提到的原理,顯而易見,合成新視點時候只需要將左影象的畫素點位置向右移動alpha *dmax,或者右影象的畫素點向左移動(1-alpha)*dmax,就可以得到alpha位置處虛擬相機拍攝的虛擬視點影象。

  合成虛擬檢視即可以利用左參考影象和對應的左視差圖,也可以利用右參考影象和對應的右視差圖,更好的是都利用上得到兩幅虛擬視點影象,然後做影象融合,比如基於距離的線性融合等。

  在演算法的實現中,又有兩種選擇,一個是正向對映,一個是反向對映(逆向對映)。

  1.正向對映

  ① 將原參考影象中整數畫素點根據其對應上視差值平移到新檢視上。

  ② 平移後像素點座標可能不是整數,為了獲取整數座標,採用最近鄰插值,將原影象畫素值賦值到新座標位置。

  ③ 由於最近鄰插值會損失精度,因此在物體的邊緣會出現鋸齒效應。

  2.反向對映

  ① 利用參考視點的視差圖dispL,算出虛擬視點位置的視差圖dispV;

  ② 由於遮擋等因素影響,dispV肯定會出現空洞和裂紋,所以需要做一個空洞填充holeFilling;

  ③ 利用dispV將虛擬視點影象中的整數座標平移到參考視點位置下的座標,此時也可能不是整數,而是浮點數座標。這就面臨一個從哪裡取值的問題。

  ④ 取參考視點影象浮點數座標附近4個點的畫素值,用雙線性插值算出對應虛擬視點影象位置處的畫素值即可。

  ⑤ 由於雙線性插值屬於一種加權平均的思想,能夠有效避免精度損失造成的鋸齒現象,但是演算法複雜度要高。

  下面給出利用左視點影象和對應視差圖獲取虛擬視點位置影象的效果(反向對映+雙線性插值):

    不進行空洞填充

空洞填充

二、利用深度圖合成虛擬視點

  和利用視差圖合成新視點一樣,利用深度圖合成新視點也有兩種選擇:1. 正向對映  2. 反向對映。由於正向對映比較簡單並且效果不理想,因此目前大多采用反向對映方法。

  已知內參矩陣K,下面仍然以左影象imgL和depthL為參考影象,獲取alpha=0.5位置處的虛擬視點影象,簡要步驟如下:

  (1). 利用內參矩陣K, 將depthL對映到三維空間點,平移到虛擬相機座標下後,重投影到虛擬視點影象平面,得到虛擬視點位置處的深度圖depthV;

  (2). 對depthV進行空洞填充;

  (3). 利用內參矩陣K和深度圖depthV,將虛擬視點影象imgV上的座標點反向投影到三維空間點,平移後再重投影到參考影象imgL上, 在imgL上利用雙線性插值獲取imgV上的畫素值。

  具體流程如下:

  (1). 利用內參矩陣K,以及參考深度圖depthL,如下圖,將參考影象座標點(u, v)投影到參考相機的攝像機座標系下,得到對應的三維空間點(X, Y, Z),計算方法如下:

d * u =  fx * X + cx *Z
d * v = fy * Y + cy * Z
d = Z

  其中d是深度值,fx, fy, cx, cy均從內參矩陣中得到,那麼(X, Y, Z)可以表示如下:

X = ( u - cx ) * d / fx
Y = ( v - cy ) * d / fy
Z = d

  參考深度圖depthL                                                                            參考左影象imgL

    參考影象左深度圖   

  (2). 將三維點(X, Y, Z)平移到虛擬攝像機座標系下,得到虛擬攝像機座標系下的三維點(X1, Y1, Z1), 計算如下:

X1 = X - alpha * baseline
Y1 = Y
Z1 = Z

  (3). 將(X1, Y1, Z1)重投影到虛擬視點圖上,得到座標(u1, v1):

u1 = ( fx * X1 + cx * d ) / d
v1 = ( fy * Y1 + cy * d ) / d
d = Z1
//注意此處d != 0

  利用最近鄰插值得到虛擬視點深度圖depthV。如下圖所示,alpha=0.5位置虛擬視點深度圖:

  (4). 對depthV進行空洞填充。填充後depthV如下圖:

  (5). 利用depthV和內參矩陣K,反向重複上述操作。將虛擬視點影象imgV座標點反向投影到三維點,平移,再重投影到參考檢視imgL上,在imgL上利用雙線性插值得到imgV上的畫素值。從而獲取虛擬視點影象imgV,如下圖:

  (6). 綜合上述步驟,可以獲取alpha從0 到 1, 也就是從左相機位置到右相機位置的一系列虛擬視點影象,gif動圖展示如下:

 上面效果中在深度不連續區域有較為明顯的失真,這是由於該區域為遮擋區域,無法計算出準確的視差值,可以通過觀察前面立體匹配部落格的視差圖或者深度圖看出。而採用的空洞填充將附近的視差值填充過去,所以會造成前景出現在背景部分,出現較為明顯的偽影。去除偽影也有很多種方法,比如結合右參考相機合成同樣位置的虛擬視點,然後將兩個視點融合等方法。

  其實3D Warping技術的核心就是下面幾條語句,二維影象點到三維空間點,平移,旋轉,再重投影到新的二維影象點。上面沒有加入旋轉,旋轉的話就是直接用三維點乘以3x3的旋轉矩陣後平移,然後再重投影。

float dep = pDepthV[i*imgW + j];
if (dep < 0.001) continue;
//反投影
float X = (j - cx)*dep / fx;
float Y = (i - cy)*dep / fy;
float Z = dep;
//平移
float X2 = X + offsetX;
float Y2 = Y;
float Z2 = Z;
//重投影
float uf = (fx*X2 + cx* Z2) / dep;
float vf = (fy*Y2 + cy * Z2) / dep;

相關推薦

真實場景虛擬視點合成View Synthsis

  上一篇部落格中介紹了從拍攝影象到獲取視差圖以及深度圖的過程,現在開始介紹利用視差圖或者深度圖進行虛擬視點的合成。虛擬視點合成是指利用已知的參考相機拍攝的影象合成出參考相機之間的虛擬相機位置拍攝的影象,能夠獲取更多視角下的圖片,在VR中應用前景很大。   視差圖可以轉換為深度圖,深度圖也可以轉換為視差圖。視

VMware虛擬機文件後綴

blank mdk 記錄 tom 而不是 我們 sun 編輯 right VMware虛擬機文件(後綴)詳解 虛擬機的文件管理由VMware Workstation來執行,一個虛擬機一般以一系列文件的形式儲存在宿主機中,這些文件一般在由workstation為虛

CentOS7安裝KVM虛擬機器Windows Server2016

5800+顯示編號: VNC的httpd監聽埠,如果VNC客戶端為IE,Firefox等非vncviewer時必須開放。5900+顯示編號: VNC服務端與客戶端通訊的真正埠,必須無條件開放。6000+顯示編號: X監聽埠,可選。顯示編號、開放的埠分別由/etc/sysconfig/vncservers檔案中

linux下tty,控制檯,虛擬終端,串列埠,console控制檯終端

首先: 1。終端和控制檯都不是個人電腦的概念,而是多人共用的小型中型大型計算機上的概念.一臺主機,連很多終端,終端為主機提供了人機介面,每個人都通過終端使用主機的資源. 終端有字元啞終端和圖形終端兩種.控制檯是另一種人機介面, 不通過終端與主機相連, 而是通過顯示卡-顯示器和

#26 Linux kernel內核與uname、lsmod、modinfo、depmod、insmod、rmmod、modprobe...命令用法

linux kernel(內核)詳解與uname、lsmod、modinfo、depmod、insmod、rmmod、modprobe...命令用法Linux kernel: 內核設計流派: 單內核設計,但是充分借鑒了微內核體系設計的優點,為內核引入了模塊化機制,內核高度模塊化; 內核被模塊化之

C++11Mutex互斥鎖

AR c++ 條件 oid 簡單 但是 資源 void AD 多個線程訪問同一資源時,為了保證數據的一致性,最簡單的方式就是使用 mutex(互斥鎖)。 (1).直接操作 mutex,即直接調用 mutex 的 lock / unlock 函數。此例順帶使用了 boost:

java 內部類inner class

ron isp https nerd 對象 重寫 prot print 元素 優點 ⒈ 內部類對象可以訪問創建它的對象的實現,包括私有數據; ⒉ 內部類不為同一包的其他類所見,具有很好的封裝性; ⒊ 使用內部類可以很方便的編寫事件驅動程序; ⒋ 匿名內部類可以方便的定義運行

調用高德地圖API熱力圖

ocs use map asc type contain maps key script 具體腳本語言如下: <!doctype html> <html> <head> <meta charset="utf-8">

Android 學習之《第一行程式碼》第二版 筆記十一廣播機制

一、廣播機制簡介 1. 四大元件之一 2. Android 提供了一套完整的API,允許應用程式自由地傳送和接收廣播。 A. 傳送廣播藉助Intent B. 接收廣播藉助廣播接收器(Broadcast Receiver) 3. 廣播型別: A. 標準廣播: 完全非同步執行

Android 學習之《第一行程式碼》第二版 筆記十二廣播機制

廣播的最佳實踐——實現強制下線功能 思路:在介面上彈出一個對話方塊,讓使用者無法進行任何操作,必須點選對話方塊中的確定按鈕,然後回到登入介面即可。 一、效果圖 1. 登入介面並輸入賬號密碼 2. 登陸後的介面 3. 強制下線 4. 退回登陸的介面

Java併發十八:阻塞佇列BlockingQueue BlockingQueue阻塞佇列)詳解 二叉堆(一)之 圖文解析 和 C語言的實現 多執行緒程式設計:阻塞、併發佇列的使用總結 Java併發程式設計:阻塞佇列 java阻塞佇列 BlockingQueue阻塞佇列)詳解

阻塞佇列(BlockingQueue)是一個支援兩個附加操作的佇列。 這兩個附加的操作是:在佇列為空時,獲取元素的執行緒會等待佇列變為非空。當佇列滿時,儲存元素的執行緒會等待佇列可用。 阻塞佇列常用於生產者和消費者的場景,生產者是往佇列裡新增元素的執行緒,消費者是從佇列裡拿元素的執行緒。阻塞佇列就是生產者

蘋果個人公司型別開發者賬號申請99美元

談到蘋果開發者賬號,我們需要區分一下個人賬號、公司賬號和企業賬號這三種,還有一種是教育賬號,這個就不多說了。     個人賬號:個人申請用於開發蘋果app所使用的賬號,僅限於個人使用,申請比較容易,$99。     公司賬號:以公司的名義申請的開發者賬

【轉載】BlockingQueue阻塞佇列

注意:該隨筆內容完全引自http://wsmajunfeng.iteye.com/blog/1629354,寫的很好,非常感謝,複製過來算是個積累,怕以後找不到。 一. 前言   在新增的Concurrent包中,BlockingQueue很好的解決了多執行緒中,如何高效安全“傳輸”資

Android VCard聯絡人備份恢復匯入/匯出

原文地址為: Android VCard聯絡人備份恢復(匯入/匯出)詳解 首先我們簡單的看下在Android中聯絡人的儲存結構. 工作環境:android 2.3.3聯絡人的主要資料存放在raw_contacts和data表裡,它兩構成主從表關係。 raw_contacts表結構

替換空格空白字元

替換空格(空白字元)詳解 import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexpTest { private static String str2; /*

二叉樹Binary Tree

二叉樹本身就是遞迴定義的(wikipedia): To actually define a binary tree in general, we must allow for the possibility that only one of the children may be empty.

自動編碼器(Autoencoder)、降噪自動編碼器Denoising Autoencoder

在瞭解降噪自動編碼器之前,我們先了解一下自動編碼器。 自動編碼器(Autoencoder): 自動編碼器和PCA等方法都屬於降維方法。PCA降維方法有著一定侷限性,主要是隻對線性可分的資料降維效果較好。這種情況下,人們希望提出一種新的簡單的、自動的、可以對非線性可分資料進行的特徵提取方法

Bootmcmd_bootm.c

一、在開始之前先說明一下bootm相關的東西。 1、首先說明一下,S3C2410架構下的bootm只對sdram中的核心映象檔案進行操作(好像AT91架構提供了一段從flash複製核心映象的程式碼,不過針對s3c2410架構就沒有這段程式碼,雖然可以在u-boot下

曼哈頓距離Manhattan Distance

概念 曼哈頓距離——兩點在南北方向上的距離加上在東西方向上的距離,即d(i,j)=|xi-xj|+|yi-yj|。對於一個具有正南正北、正東正西方向規則佈局的城鎮街道,從一點到達另一點的距離正是在南北方向上旅行的距離加上在東西方向上旅行的距離,因此,曼哈頓距離又稱為計程車距離。 ——引用自百度&nb

順序表的插入操作原理及實現C語言

順序表中存放資料的特點和陣列這種資料型別完全吻合,所以順序表的實現使用的是陣列。換句話說,順序表中插入元素問題也就等同於討論如何向陣列中插入資料。 因此,順序表中插入資料元素,無非三種情況: 在表頭插入; 在表的中間某個位置插入; 直接尾隨順序表,作為表的最後一個元素; 無論在順序表的什麼位置插