參考:
pnp問題 與 solvepnp函數:https://www.jianshu.com/p/b97406d8833c
對圖片進行二維仿射變換cv2.warpAffine() or 對圖片進行二維射影變換cv2.warpPerspective :https://www.jianshu.com/p/1c6512d475cc
關鍵:今天裁圖過程中發現裁出來的一些圖較正常圖發生了奇怪的仿射變換,最后發現是solvepnp求解出的頭部坐標系到攝像機坐標系的RT有錯誤,改用solvepnpRansac之后得到解決。
//cv::solvePnP(p_3d17, p_2d17, camInstris, camDistort, cam_r, cam_t); cv::solvePnPRansac(p_3d17, p_2d17, camInstris, camDistort, cam_r, cam_t, true, 1000, 1, 0.99);
solvepnpRansac比solvepnp多出了三個參數,1000為算法迭代次數。
pnp問題介紹
如果場景的三維結構已知,利用多個控制點在三維場景中的坐標及其在圖像中的透視投影坐標即可求解出攝像機坐標系與表示三維場景結構的世界坐標系之間的絕對位姿關系,包括絕對平移向量t以及旋轉矩陣R,該類求解方法統稱為N點透視位姿求解(Perspective-N-Point,PNP問題)。這里的控制點是指准確知道三維空間坐標位置,同時也知道對應圖像平面坐標的點。對於透視投影來說,要使得PNP問題有確定解,需要至少三組控制點。


經典的P3P問題可以轉化為一個四面體形狀的確定問題,如圖所示。即已知條件為知道控制點 A,B,C的位置以及在攝像機中的投影坐標求棱長邊a,b,c的問題。通過余弦定理,再利用點雲配准方法可以得到攝像機坐標系相對於世界坐標系的平移以及旋轉。圖中的P點相當於相機的光心,A,B,C相當於世界坐標系下已知相對位置關系的三個控制點,A',B',C'為圖像坐標系中對應的三個點。PNP解決的是純數學問題,數學證明在此處省略。
Opencv中PNP的求解函數
solvepnp
void solvePnP(InputArray objectPoints, InputArray imagePoints, InputArray cameraMatrix, InputArray distCoeffs, OutputArray rvec, OutputArray tvec, bool useExtrinsicGuess=false, int flags = CV_ITERATIVE)
Parameters:
objectPoints - 世界坐標系下的控制點的坐標,vector<Point3f>的數據類型在這里可以使用
imagePoints - 在圖像坐標系下對應的控制點的坐標。vector<Point2f>在這里可以使用
cameraMatrix - 相機的內參矩陣
distCoeffs - 相機的畸變系數
以上兩個參數通過相機標定可以得到。相機的內參數的標定參見:http://www.cnblogs.com/star91/p/6012425.html
rvec - 輸出的旋轉向量。使坐標點從世界坐標系旋轉到相機坐標系
tvec - 輸出的平移向量。使坐標點從世界坐標系平移到相機坐標系
flags - 默認使用CV_ITERATIV迭代法
solvepnpRansac
應用了pnp算法,提高了精度。