有關ReprojectImageTo3D的點雲長得奇怪的解決方案

給老闆寫的,再一次懶得翻譯成中文了……

==========================================================

先放結果!


(左右兩幅原始圖像)再見顯然不是我的特斯拉……

    

-----------------------------------------------------------------------------------------------------------------------------------

(disparity map)

-------------------------------------------------------------------

(點雲/ point cloud)






==== 概括 ===========================================================================================================

主要的意思就是,其實opencv的reprojectImageTo3D沒有問題。

(很多網上說這個function有問題, 比如這個stackoverflow的鏈接, 我遇到了和作者一摸一樣的問題。他最後通過自己寫了一遍reprojectImageTo3D函數就好了。http://stackoverflow.com/questions/22418846/reprojectimageto3d-in-opencv ,我也嘗試自己寫這個function但還是結果不理想,最後繞了一圈再用這個函數結果就對拉)


個人覺得這部分要注意的三點是:

1. 得到disparity map的過程中,參數要調對(texture treshold設大, 這樣減少很多噪聲。噪聲太多的話點雲就算對了也看不出來是什麼)disparity map看上去一定要很好很好。噪聲越少越好。我的uniqueRatio倒是很小……目測只有1~2的樣子。

2. Q 矩陣要對~ 這個基本好好做calibration應該沒大問題。我直接用了openCV 中的stereo calibration,並沒有分別先做monocular calibration,效果依舊很不錯。

3. 用reprojectImageTo3D之後,我用meshlab顯示出來,zoom in 一下就好啦。


==== 正文 ==================================================================================================================

1. get good disparity map, play with the parameters of block matching algorithm


my experience is:

  • for closer object to be detected, NumofDisparities should be large, and vice versa

  • set SADWindowSize to be big

  • set UniqueRatio to 1~10

  • set TextureTreshold to be large enough (try 400~500)


2. Use ReprojectImageTo3D()


Suppose we get such disparity map:

disp.jpg



use:

reprojectImageTo3D(disparity, XYZ, Q,true,-1);


sethandleMissingValues to TRUE!!!


and we get:


3. Set threshold to the point cloud to get rid of the points far away from camera


Set threshold to ignore points which are too close to/ too far away from the cameras.

Example code:


void saveXYZ(constchar* filename,constMat& mat)

{

constdouble max_z =1.0e4;

FILE* fp = fopen(filename,"wt");

for(int y =0; y < mat.rows; y++)

{

for(int x =0; x < mat.cols; x++)

{

Vec3f point = mat.at<Vec3f>(y, x);

if(fabs(point[2]- max_z)< FLT_EPSILON || fabs(point[2])> max_z)continue;

if(point[2]>300)continue;

fprintf(fp,"%f %f %f \n", point[0], point[1], point[2]);

}

}

fclose(fp);

}



4. put XYZ.txt to Meshlab to see the result

:)

1.PNG

4.PNG



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章