2014-06-22 65 views
1

我目前在一個立體視覺項目中工作,其中我應該從每個相機視圖中找到的對應關係重建3D點,並且爲此我使用的是OpenCV 2.4.7爲C++。三維重建三維重建問題opencv

我能夠正確校準兩臺攝像機,計算基本矩陣,計算重新投影矩陣,並糾正圖像。

我的問題在於項目的最後部分,它是從2D點對應計算3D世界座標。我已經嘗試使用cv :: triangulatePoints,但是座標爲(0,0,0)的點的結果,無論輸入點是什麼。我也嘗試了Hartley的線性三角測量算法& Strum,但是這也沒有給我帶來好的結果。

有人可以告訴我應該使用什麼功能嗎?或者,也許有一些關於如何正確實施我所談論的技巧的提示。我最大的問題是要在互聯網上找到好的文檔,所以我決定在這裏提問。

謝謝!

+0

您可能會將錯誤的輸入傳遞給'triangulatePoints'方法。檢查這個其他問題:http://stackoverflow.com/questions/16295551/how-to-correctly-use-cvtriangulatepoints – Esparver

回答

0

我也試過cv :: triangulatePoints,它會計算垃圾。我被迫執行手動線性三角測量方法,該方法返回該三角3D點4×1矩陣:

Mat triangulate_Linear_LS(Mat mat_P_l, Mat mat_P_r, Mat warped_back_l, Mat warped_back_r) 
{ 
    Mat A(4,3,CV_64FC1), b(4,1,CV_64FC1), X(3,1,CV_64FC1), X_homogeneous(4,1,CV_64FC1), W(1,1,CV_64FC1); 
    W.at<double>(0,0) = 1.0; 
    A.at<double>(0,0) = (warped_back_l.at<double>(0,0)/warped_back_l.at<double>(2,0))*mat_P_l.at<double>(2,0) - mat_P_l.at<double>(0,0); 
    A.at<double>(0,1) = (warped_back_l.at<double>(0,0)/warped_back_l.at<double>(2,0))*mat_P_l.at<double>(2,1) - mat_P_l.at<double>(0,1); 
    A.at<double>(0,2) = (warped_back_l.at<double>(0,0)/warped_back_l.at<double>(2,0))*mat_P_l.at<double>(2,2) - mat_P_l.at<double>(0,2); 
    A.at<double>(1,0) = (warped_back_l.at<double>(1,0)/warped_back_l.at<double>(2,0))*mat_P_l.at<double>(2,0) - mat_P_l.at<double>(1,0); 
    A.at<double>(1,1) = (warped_back_l.at<double>(1,0)/warped_back_l.at<double>(2,0))*mat_P_l.at<double>(2,1) - mat_P_l.at<double>(1,1); 
    A.at<double>(1,2) = (warped_back_l.at<double>(1,0)/warped_back_l.at<double>(2,0))*mat_P_l.at<double>(2,2) - mat_P_l.at<double>(1,2); 
    A.at<double>(2,0) = (warped_back_r.at<double>(0,0)/warped_back_r.at<double>(2,0))*mat_P_r.at<double>(2,0) - mat_P_r.at<double>(0,0); 
    A.at<double>(2,1) = (warped_back_r.at<double>(0,0)/warped_back_r.at<double>(2,0))*mat_P_r.at<double>(2,1) - mat_P_r.at<double>(0,1); 
    A.at<double>(2,2) = (warped_back_r.at<double>(0,0)/warped_back_r.at<double>(2,0))*mat_P_r.at<double>(2,2) - mat_P_r.at<double>(0,2); 
    A.at<double>(3,0) = (warped_back_r.at<double>(1,0)/warped_back_r.at<double>(2,0))*mat_P_r.at<double>(2,0) - mat_P_r.at<double>(1,0); 
    A.at<double>(3,1) = (warped_back_r.at<double>(1,0)/warped_back_r.at<double>(2,0))*mat_P_r.at<double>(2,1) - mat_P_r.at<double>(1,1); 
    A.at<double>(3,2) = (warped_back_r.at<double>(1,0)/warped_back_r.at<double>(2,0))*mat_P_r.at<double>(2,2) - mat_P_r.at<double>(1,2); 
    b.at<double>(0,0) = -((warped_back_l.at<double>(0,0)/warped_back_l.at<double>(2,0))*mat_P_l.at<double>(2,3) - mat_P_l.at<double>(0,3)); 
    b.at<double>(1,0) = -((warped_back_l.at<double>(1,0)/warped_back_l.at<double>(2,0))*mat_P_l.at<double>(2,3) - mat_P_l.at<double>(1,3)); 
    b.at<double>(2,0) = -((warped_back_r.at<double>(0,0)/warped_back_r.at<double>(2,0))*mat_P_r.at<double>(2,3) - mat_P_r.at<double>(0,3)); 
    b.at<double>(3,0) = -((warped_back_r.at<double>(1,0)/warped_back_r.at<double>(2,0))*mat_P_r.at<double>(2,3) - mat_P_r.at<double>(1,3)); 
    solve(A,b,X,DECOMP_SVD); 
    vconcat(X,W,X_homogeneous); 
    return X_homogeneous; 
} 

的輸入參數是兩個3x4的相機投影矩陣和左/右對應的像素的座標(X,Y ,W)。

+0

做你自己的忙,並使用'Mat_ '這種冒險,然後你可以跳過'在'部分,訪問是例如一個不錯的'b(1,0)'。可讀性/清晰度方面的巨大收益 – berak

+0

有一天我會嘗試一下 – YuZ