當前位置:首頁 >教程首頁 > Unreal Engine >如何在UE4中進行真實相機的標定、畸變模擬與矯正?

如何在UE4中進行真實相機的標定、畸變模擬與矯正?

發布時間:2020-12-25 19:02:17

教程適用

品牌型號: 惠普暗影精靈3

係統版本:Windows10  專業版

軟件版本:unreal engine 4 v4.5


隨著虛幻引擎在影視虛擬製作領域以及模擬仿真領域比如自動駕駛仿真等的不斷深入應用,如何在虛幻引擎中模擬真實相機的機製已成”剛需“。這篇文章會和大家介紹下如何在虛幻引擎4.24中進行真實相機的標定、畸變模擬與矯正。

首先來認識下這次的主角, 打開Plugins窗口,搜索“Lens Distortion”, 結果會如下圖列出兩個關於鏡頭畸變模擬的插件,今天我們主要聊聊最新的“OpenCV Lens Distortion”插件,至於兩者的異同,我們會在下文中進行說明。將插件啟用,然後重啟項目,正式開始!

0.png

一、相機的標定

要模擬或者矯正相機畸變,首先需要進行相機標定,從而計算出相機內參。顧名思義,這款內置插件是基於OpenCV的相機模型來工作的。相機內參主要包括徑向、切向畸變係數,縱、橫向焦距以及光學中心在最終畫麵上的位置,這些都是由於實際相機或者鏡頭製造精度或者裝配誤差所造成的不完美。這款插件的標定是基於OpenCV默認的相機標定方法--張正友標定法。方法的具體的操作流程,網上資料很多,就不在此贅述。

插件提供了兩種方法進行相機標定。

1.使用圖片文件標定

一種方式是將一組包含棋盤格的圖片輸入給標定器(Calibrator)。這些圖片上的棋盤格組合起來需要能基本覆蓋整個畫麵,棋盤格畫麵需要清晰。采集時要緩慢轉動或者索性在靜止時截圖來避免運動模糊導致的誤差。下邊的一組示例圖片中存在著一些不足,一是每張圖片上的棋盤格占畫麵比例過低,導致需要采集更多的圖片;二是棋盤格沒有覆蓋到右上角區域,這容易導致計算出的內參在右上角出現較大誤差; 三是每個區域不同角度的棋盤格張數有限,這也是潛在影響標定精度的因素之一。

1.png

接下來看下具體如何實現,創建一個基於Actor的藍圖類,稱之為”BP_CamDistortionMgr”。接著添加一個”BeginCalibration”函數,實現如下圖。核心是調用”Create Calibrator”創建標定器,“Board Width/Height” 分別指橫向縱向的內部邊數(格子數-1),“Square Size”即是每個格子的邊長(厘米)。

2.png

創建另一個“Calibrate from Images” 函數,將一組圖片逐一”喂“給標定器。

3.png

循環結束後,調用“EndCalibration”函數,計算相機內參。“EndCalibration”函數實現如下圖,如果”Calculate Lens Parameters” 計算返回True,應該進一步檢查“Margin of Error”來查看誤差,如果誤差也小於一個閾值(根據項目需求的一個經驗值),那麼認為標定成功,此時將“Lens Distortion Parameters”以及”Camera View Info”保存下來。

4.png

2. 使用視頻實時標定

當然你也可以用另一種實時視頻采集的方式來進行標定。由於手裏沒有采集卡這裏以視頻文件為例,按照官方文檔, 創建一個Material來顯示Media Texture上的內容。這裏要注意如果將Media Texture 拖到一個Mesh上,默認創建的Material是將Media Texture Sample 輸出到 Base Color Channel, 而這裏因為後續“Draw Material to Render Target” 的需要,應該輸出到Emissive Color Channel。

5.png

然後創建一個Render Target, 格式采用RGBA8 即可, 大小和視頻畫麵一致。然後通過“Draw Material to Render Target” 將Media Texture 轉到 Render Target上 然後進一步”喂“給標定器。可以每次Tick調用“Calibrate Current Frame”也可以采用其他諸如按鍵等方式來觸發。當采集了足夠多的畫麵後,再調用上文的“EndCalibration”得到內參。

6.png

二、相機的畸變模擬與矯正

1. 預計算Displacement Map

插件從效率考慮,通過預計算將畸變模擬和矯正的uv offset預先存儲在一張Displacement Map中,從而可以在運行時通過一次采樣獲得相應的uv offset值。Displacement Map可以通過以下藍圖來生成。此處的Render Target基於精度考量使用RGBA32f格式,其大小與輸入視頻尺寸相同或者等比例縮放。

7.png

需要注意這裏的Cropping Factor, 其決定在計算Displacment Map時,是否對其進行縮放使得矯正後的圖像中不會出現黑色區域,反之則是保留所有原始圖像的像素,但邊緣會有黑色區域。

8.webp.jpg

左: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。

9.png

最後在CineCameraActor的紅框參數輸入與實拍相機一致的參數,其中“Current Focal Length”應該使用標定得出的“Camera View Info”中的“Focal Length”值。

10.png

這裏值得注意的是由於我們並沒有將相機的內參比如Principal Point直接作用在相機的投影矩陣上, 這就可能導致有些物體會在遮擋階段被錯誤的剔除,從而在某些情況下造成畫麵的邊緣偶爾的顯示錯誤。

三、進一步的思考

1. 關於易用性

不同於OpenCV計算得到的相機內參,插件計算得到的Fx,Fy, Cx,Cy都做了歸一化處理,而不是以像素為單位,這樣的好處是你可以更方便的處理相同長寬比的不同分辨率的圖像,比如你校準的時候輸入圖像為1920x1080,那麼你可以很方便的用同一套內參去模擬3840x2160或者960x540的情況。(當然前提是你並沒有改變Focal Length,Focus Distance等會影響內參的參數)

如果想要同一組相機內參模擬不同長寬比的分辨率的情況,那麼你需要了解這不同分辨率在相機感光元件(CMOS/CCD)上所使用的成像麵積之間的關係來進一步換算。

除此以外,插件也考慮到了OpenCV相機坐標係和UE坐標係的不同,已經做了相應轉換。

2. 為什麼用預計算Displacement Map的方式

之所以使用預計算的方式,顯然是因為性能的考量。OpenCV文檔上可以看到畸變矯正可以通過下麵的公式來計算矯正後的像素坐標,顯而易見沒有必要在運行時來做,預計算後一次采樣操作要輕鬆愉快的多。

11.webp.jpg

來自: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點可以說精度上第二個插件理論上會更好。

來源於虛幻引擎

作者周澄清

华体会hth体育网 賞析
  • 2101期學員李思庭作品

    2101期學員李思庭作品

  • 2104期學員林雪茹作品

    2104期學員林雪茹作品

  • 2107期學員趙淩作品

    2107期學員趙淩作品

  • 2107期學員趙燃作品

    2107期學員趙燃作品

  • 2106期學員徐正浩作品

    2106期學員徐正浩作品

  • 2106期學員弓莉作品

    2106期學員弓莉作品

  • 2105期學員白羽新作品

    2105期學員白羽新作品

  • 2107期學員王佳蕊作品

    2107期學員王佳蕊作品

專業問題谘詢

你擔心的問題,火星幫你解答

微信掃碼入群領福利

掃碼領福利最新AI資訊

點擊谘詢
添加老師微信,馬上領取免費課程資源

1. 打開微信掃一掃,掃描左側二維碼

2. 添加老師微信,馬上領取免費課程資源

×

同學您好!

您已成功報名0元試學活動,老師會在第一時間與您取得聯係,請保持電話暢通!
確定