教程適用
品牌型號: 惠普暗影精靈3
係統版本:Windows10 專業版
軟件版本:unreal engine 4 v4.5
隨著虛幻引擎在影視虛擬製作領域以及模擬仿真領域比如自動駕駛仿真等的不斷深入應用,如何在虛幻引擎中模擬真實相機的機製已成”剛需“。這篇文章會和大家介紹下如何在虛幻引擎4.24中進行真實相機的標定、畸變模擬與矯正。
首先來認識下這次的主角, 打開Plugins窗口,搜索“Lens Distortion”, 結果會如下圖列出兩個關於鏡頭畸變模擬的插件,今天我們主要聊聊最新的“OpenCV Lens Distortion”插件,至於兩者的異同,我們會在下文中進行說明。將插件啟用,然後重啟項目,正式開始!
一、相機的標定
要模擬或者矯正相機畸變,首先需要進行相機標定,從而計算出相機內參。顧名思義,這款內置插件是基於OpenCV的相機模型來工作的。相機內參主要包括徑向、切向畸變係數,縱、橫向焦距以及光學中心在最終畫麵上的位置,這些都是由於實際相機或者鏡頭製造精度或者裝配誤差所造成的不完美。這款插件的標定是基於OpenCV默認的相機標定方法--張正友標定法。方法的具體的操作流程,網上資料很多,就不在此贅述。
插件提供了兩種方法進行相機標定。
1.使用圖片文件標定
一種方式是將一組包含棋盤格的圖片輸入給標定器(Calibrator)。這些圖片上的棋盤格組合起來需要能基本覆蓋整個畫麵,棋盤格畫麵需要清晰。采集時要緩慢轉動或者索性在靜止時截圖來避免運動模糊導致的誤差。下邊的一組示例圖片中存在著一些不足,一是每張圖片上的棋盤格占畫麵比例過低,導致需要采集更多的圖片;二是棋盤格沒有覆蓋到右上角區域,這容易導致計算出的內參在右上角出現較大誤差; 三是每個區域不同角度的棋盤格張數有限,這也是潛在影響標定精度的因素之一。
接下來看下具體如何實現,創建一個基於Actor的藍圖類,稱之為”BP_CamDistortionMgr”。接著添加一個”BeginCalibration”函數,實現如下圖。核心是調用”Create Calibrator”創建標定器,“Board Width/Height” 分別指橫向縱向的內部邊數(格子數-1),“Square Size”即是每個格子的邊長(厘米)。
創建另一個“Calibrate from Images” 函數,將一組圖片逐一”喂“給標定器。
循環結束後,調用“EndCalibration”函數,計算相機內參。“EndCalibration”函數實現如下圖,如果”Calculate Lens Parameters” 計算返回True,應該進一步檢查“Margin of Error”來查看誤差,如果誤差也小於一個閾值(根據項目需求的一個經驗值),那麼認為標定成功,此時將“Lens Distortion Parameters”以及”Camera View Info”保存下來。
2. 使用視頻實時標定
當然你也可以用另一種實時視頻采集的方式來進行標定。由於手裏沒有采集卡這裏以視頻文件為例,按照官方文檔, 創建一個Material來顯示Media Texture上的內容。這裏要注意如果將Media Texture 拖到一個Mesh上,默認創建的Material是將Media Texture Sample 輸出到 Base Color Channel, 而這裏因為後續“Draw Material to Render Target” 的需要,應該輸出到Emissive Color Channel。
然後創建一個Render Target, 格式采用RGBA8 即可, 大小和視頻畫麵一致。然後通過“Draw Material to Render Target” 將Media Texture 轉到 Render Target上 然後進一步”喂“給標定器。可以每次Tick調用“Calibrate Current Frame”也可以采用其他諸如按鍵等方式來觸發。當采集了足夠多的畫麵後,再調用上文的“EndCalibration”得到內參。
二、相機的畸變模擬與矯正
1. 預計算Displacement Map
插件從效率考慮,通過預計算將畸變模擬和矯正的uv offset預先存儲在一張Displacement Map中,從而可以在運行時通過一次采樣獲得相應的uv offset值。Displacement Map可以通過以下藍圖來生成。此處的Render Target基於精度考量使用RGBA32f格式,其大小與輸入視頻尺寸相同或者等比例縮放。
需要注意這裏的Cropping Factor, 其決定在計算Displacment Map時,是否對其進行縮放使得矯正後的圖像中不會出現黑色區域,反之則是保留所有原始圖像的像素,但邊緣會有黑色區域。
左:Cropping Factor = 0 右:Cropping Factor = 1
2. 使用Post Process Material模擬或矯正畸變
有了Displacement Map後就可以很方便來模擬畸變或者矯正畸變了,創建一個Post Process Material,將其設在CineCamereActor的Post Porcess/Rendering Features/Post Process Materials裏。如下圖所示,Displacement Map 的Red、Green Channel上存儲畸變矯正的uv offset, 而Blue、Alpha Channel則存儲著畸變模擬的uv offset,設置ToggleDistortAndUnDistort設為0,1來切換矯正畸變還是模擬畸變。Enable PP 設為0或1 控製開啟或者關閉這個PP。
比如我們需要將UE渲染出的虛擬畫麵模擬畸變從而能和實拍畫麵進行合成,那麼應該將 EnablePP與ToggleDistortAndUndistort設為1。
最後在CineCameraActor的紅框參數輸入與實拍相機一致的參數,其中“Current Focal Length”應該使用標定得出的“Camera View Info”中的“Focal Length”值。
這裏值得注意的是由於我們並沒有將相機的內參比如Principal Point直接作用在相機的投影矩陣上, 這就可能導致有些物體會在遮擋階段被錯誤的剔除,從而在某些情況下造成畫麵的邊緣偶爾的顯示錯誤。
三、進一步的思考
1. 關於易用性
不同於OpenCV計算得到的相機內參,插件計算得到的Fx,Fy, Cx,Cy都做了歸一化處理,而不是以像素為單位,這樣的好處是你可以更方便的處理相同長寬比的不同分辨率的圖像,比如你校準的時候輸入圖像為1920x1080,那麼你可以很方便的用同一套內參去模擬3840x2160或者960x540的情況。(當然前提是你並沒有改變Focal Length,Focus Distance等會影響內參的參數)
如果想要同一組相機內參模擬不同長寬比的分辨率的情況,那麼你需要了解這不同分辨率在相機感光元件(CMOS/CCD)上所使用的成像麵積之間的關係來進一步換算。
除此以外,插件也考慮到了OpenCV相機坐標係和UE坐標係的不同,已經做了相應轉換。
2. 為什麼用預計算Displacement Map的方式
之所以使用預計算的方式,顯然是因為性能的考量。OpenCV文檔上可以看到畸變矯正可以通過下麵的公式來計算矯正後的像素坐標,顯而易見沒有必要在運行時來做,預計算後一次采樣操作要輕鬆愉快的多。
來自:https://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html
更重要的是如果要進行逆計算--畸變的模擬,你需要使用諸如牛頓迭代法等方式來求解,對GPU很不友好。這裏插件的實現用了一個巧妙的方法用一個pass解決了畸變模擬和矯正的預計算。VS假設輸入的Grid(默認32x32)的頂點是畸變後的坐標,然後通過采樣預計算的“Undistort UV Displacement Map”,得到矯正後的位置,將矯正後的位置作為SvPosition傳給PS,同時將原始的坐標作為Texcoord 傳給PS, 在PS中將Texcoord坐標減去SvPosiiton 就得到了undistort to distort的uv offset; distort to undistort 則比較簡單,PS 同時將SvPosition當作distort後的值,sample undistortDisplacementMap就能求得undistort的坐標,相減得到反向的uv offset。
(參見\Engine\Plugins\Compositing\OpenCVLensDistortion\Shaders\Private\DisplacementMapGeneration.usf)
3. 關於精度
從上文的解釋可知,精度與輸入圖像的分辨率、質量,以及與“Undistort UV Displacement Map”以及最後的“Displacement Map”大小有關。另外需要注意的是對於畸變的模擬,由於他是將32x32的Grid在VS中計算undistort的坐標, 而傳入PS後頂點之間是線性插值的,所以會影響精度,如果需要提高其精度那麼需要修改代碼中的kGridSubdivisionX/Y的值來提高Grid的密度。
4. 兩個Lens Distortion插件的異同
最後來回答文章開頭的問題就更容易理解了,其實兩者用的camera model是一樣的,所以其背後的原理也是類似的,區別在於:(下文第一個表示“Lens Distortion”插件,第二個表示”OpenCV Lens Distortion”插件“)
第一個用的是個簡化的模型,隻包含了畸變係數的前幾項,絕大多數情況下也夠用了。
第一個插件並沒有標定功能。
第一個插件利用Shader直接生成了Displacement map,相當於把第二個插件中”Create Undistort UVDisplacment Map”的工作也放在了shader中完成,而第二個插件則是調用OpenCV的API用CPU來完成的,所以效率上第一個會更勝一籌,但生成map畢竟隻是預計算的一步,快慢其實並不很重要,當然如果不想預計算所需用到的所有Displacement Map,而是直接在runtime根據實時的內參動態來生成的話,第一個才是你的”菜“。
接著第三條,因為Shader計算浮點數精度為32位,而在OpenCV相應API內使用的是64位浮點精度來進行計算,再結合第1點可以說精度上第二個插件理論上會更好。
來源於虛幻引擎
作者周澄清
上一篇 UE4冰材質製作分享圖文教程
熱門課程
專業講師指導 快速擺脫技能困惑相關文章
多種教程 總有一個適合自己專業問題谘詢
你擔心的問題,火星幫你解答這篇文章詳細介紹了如何學習使用UE4進行可視化製作,以及火星時代教育對此方麵培訓的專業性
麵對繁多的移動端UI培訓機構,如何選擇一個適合自己的呢? 本文將為你解答疑問,而火星時代教育,我們敢說是最好的選擇!
基於火星時代教育的高質量課程體驗, 揭示遊戲開發的前瞻性和職業發展前景。
以UE4作為工具來建構智慧城市,能大大提高其實用性和創新性。火星時代教育通過專業的UE4課程培訓來助力學習者掌握UE4建構智慧城市的技巧。
對於很多熱愛製作遊戲特效的朋友來說,擔心的一個問題就是,學習遊戲特效需要多少時間?火星時代教育為您詳細分析和解答。
了解影視原畫設計的基本知識和學習路徑,尤其是在火星時代教育的專業指導下,你將擁有更好的學習體驗。
1. 打開微信掃一掃,掃描左側二維碼
2. 添加老師微信,馬上領取免費課程資源
同學您好!