星期二, 5月 19, 2015

cornerSubPix

Camera calibration with OpenCV 有強調, 以 camera 即時取圖時,仍要有間隔,以取得不同的 image。因為相似的 image 會導致 similar equations,而 similar equations 在校正階段,會導致 ill-posed problem。文中建議, findChessboardCorerns 後,再用 cornerSubPix 再找 image points。

Similar position 導致的 similar equation 的破壞力究竟多大?我還不確定。本來以為只是會 over-fitting 某些視角。但目前只要相似圖,undistortion 的結果就很慘。而相近的那幾張圖也沒有特別好。

文中建議的 cornerSubPix 指出,我們所面對的 image points,不該用有限解析度的整數點位置,而是有小數點的真實位置。學習重點:
1) cornerSubPix 的使用
2) 逼近 "真實位置" 的原理
3) findChessboard 如果不用 fast mode,內部是否已使用 cornerSubPix ?


1) cornerSubPix 的使用
C++: void cornerSubPix(InputArray image, InputOutputArray corners, Size winSize, Size zeroZone, TermCriteriacriteria)
Python: cv2.cornerSubPix(image, corners, winSize, zeroZone, criteria) → None

image: input image . opencv 2.4.9 仍是用 gray image

corners : 重要的兼 input 和 output。本例中將 findChessboard 得到的 image points 傳入,結束後得到修正結果。opencv 2.4.9 仍是用 vector. Point2d 馬上 throw error。

size: winSize。實際對每角點的搜尋區大小是 (winSize*2+1, winSize*2+1)。

zeroZone: 搜索区域中间的dead region边长的一半,有时用于避免自相关矩阵的奇异性。如果值设为(-1,-1)则表示没有这个区域

criteria: 停止條件。cornerSubPix 是遞迭式,可設最多幾回 criteia.maxCount 或角點的回合位移小於 criteria.epsilon,若回合內移動太小,沒必要再算就停止。

2) 逼近 "真實位置" 的原理
先說 gradient 與 edge 的關係。在理想的 edge 上,p 點的梯度,與自身的 edge 方向垂直。對在同 edge 上的 q,可寫成  G(p)^t  (q - p) = 0。其中 G(p) 是 p 之梯度。
回到本題,我們想找角點 q 落在 p 附近。對 p 附近的 pi 點,已知對應梯度 D Ipi。 (這裡困惑了,貌似 pi 都該在 edge 上,但圖中 p0 顯然不在 edge 上?),角點 q 也落在這些 edge 上,所以滿足  G(pi)^t  (q - pi) = 0。

命題為找角點 q 盡可能讓 pi 梯度能垂直所有的 (pi - q)

對 searching window,加總求 q 能使 epsilon i sum 最小 

find q min. sum DIpi^t  (q - pi)

 這邊應可直接用 least square 解 q。


不過文件說用 iterative 解,可能是我們大約知道 q 的位置。文件說法,讓下式為 0




3) findChessboard 如果不用 fast mode,內部是否已使用 cornerSubPix ?
是。trace cvFindChessboardCorners(),至少在 2.4.6 版,非 fast mode,就會進入 cvFindCornerSubPix()。



沒有留言: