OpenCV畸变校正原理以及损失有效像素原理分析
????常用的張正友標定法的流程,其中獲取了攝像機的內(nèi)參矩陣K,和畸變系數(shù)D。
1.在普通相機cv模型中,畸變系數(shù)主要有下面幾個:(k1; k2; p1; p2[; k3[; k4; k5; k6]] ,其中最常用的是前面四個,k1,k2為徑向畸變系數(shù),p1,p2為切向畸變系數(shù)。
2.在fisheye模型中,畸變系數(shù)主要有下面幾個(k1,k2,k3,k4).
?
因為cv和fisheye的鏡頭畸變模型不一樣,所以畸變系數(shù)也會有所不同,具體在畸變校正時的公式也不同,具體公式請參見opencv2.0和3.0的官方文檔。OpenCV中對畸變圖像進行畸變校正主要用的函數(shù)有UndistortImage()函數(shù),以及initUndistortRectifyMap()結(jié)合remap()函數(shù)。其實UndistortImage()就是initUndistortRectifyMap()和remap()的簡單組合,效果是一樣的。
?
但是有一點是:當你有很多畸變圖像需要較正時,用UndistortImage()函數(shù)的缺點就暴露了。因為畸變坐標映射矩陣mapx和mapy只需要計算一次就足夠了,而重復調(diào)用UndistortImage()只會重復計算mapx和mapy,嚴重影響程序效率。因此當有多張圖片要畸變校正時,建議使用一次initUndistortRectifyMap(),獲取畸變坐標映射矩陣mapx和mapy后,作為remap函數(shù)的輸入,多次調(diào)用remap函數(shù)進行畸變校正。
?
今天要說的第二點就是做過畸變校正的同學都知道,畸變校正后的圖像會損失很多像素,這是為什么呢?接下來就以常見的桶形畸變?yōu)槔治鲆幌?#xff1a;由于我目前手頭的相機畸變程度并不明顯(之前用廣角鏡頭的時候畸變程度相當明顯)。因此就從網(wǎng)上找一些圖片作為例子以便說明,這里引用一下圖片來源
http://www.developersite.org/904-45591-%E6%A0%87%E5%AE%9A。
畸變原圖如下:
?
畸變校正后的圖如下:
?
相信大家已經(jīng)可以看到了,由于桶形畸變的特征是,遠離圖像中心的地方成像放大率小,因此越遠離圖像中心的位置畸程度越明顯,像點越向內(nèi)移動。畸變校正后,原本擠在一起的像素點們被校正到原來的位置,就得到上面的圖像。同時由于四周的像素被拉伸,會造成四周出現(xiàn)模糊的情況。
得到上述圖像后很自然想到的是把四周的黑色區(qū)域裁掉,只留下中間的圖像區(qū)域。如下圖(紅色框):
?
那么問題來了,這樣做的話輸出圖像的長寬比和輸入圖像的長寬比就不一致了。因此opencv畸變校正函數(shù)內(nèi)部做法是:在保證長寬比不變的情況下,對上面的圖像取中間的ROI區(qū)域出來,類似進行“裁剪”操作,那么就會得到損失更多像素的輸出圖像啦,如下圖(藍色框)!
好了,說到這里,我們就把代碼中的罪魁禍首找出來吧!先看一下initUndistortRectifyMap()函數(shù)的原型,如下圖左,默認情況下,我們通常不會求取新的CameraMatrix,這樣代碼中會默認使用標定得到的CameraMatrix。而這個攝像機矩陣是在理想情況下沒有考慮畸變得到的,所以并不準確,重要的是fx和fy的值會比考慮畸變情況下的偏大,會損失很多有效像素。我們可以通過這個函數(shù)getOptimalNewCameraMatrix ()求取一個新的攝像機內(nèi)參矩陣,函數(shù)原型如下圖右,注意函數(shù)上面的備注” Return the new camera matrix based on the free scaling parameter“,通過這個函數(shù)可以自行調(diào)整縮放比例。
? ? ? ?
?
?
在getOptimalNewCameraMatrix ()函數(shù)中,其中的一個輸入?yún)?shù)為alpha∈(0,1),alpha的意義見上圖,調(diào)節(jié)alpha的值能夠控制得到的新矩陣中的fx和fy的大小,當alpha=1的時候,原圖像中的所有像素能夠得到保留,也就出現(xiàn)了上面校正后圖像中的那些黑色的空洞區(qū)域。【注:cv模型中為alpha,fisheye模型中為balance,意義是一樣的】
那么alpha是怎么樣改變 f 值的,主要是getOptimalNewCameraMatrix ()中又調(diào)用了一個函數(shù)undistortPoints(),這個函數(shù)會在畸變圖像中選取上下左右四個點進行畸變校正,具體請看源碼。下面圖片中我圈出的代碼就在這個函數(shù)里面,里面具體的f1,f2,f3,f4的意思就與取的上下左右四個點有關,可以去看源代碼,當然不明白了也可以問我。總之是在fmin和fmax之間進行插值計算 f,而通常balance(alpha)默認為0,f=fmax,焦距越大,視場越小,損失的有效像素越多。
?
好了,夜已深,今天就到這里。
轉(zhuǎn)自
總結(jié)
以上是生活随笔為你收集整理的OpenCV畸变校正原理以及损失有效像素原理分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenCV求逆(伪逆)矩阵函数
- 下一篇: OpenCV Mat数据类型及位数总结