給老闆寫的,再一次懶得翻譯成中文了……
==========================================================
先放結果!
(左右兩幅原始圖像)顯然不是我的特斯拉……
-----------------------------------------------------------------------------------------------------------------------------------
(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:
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
:)