1
我有一些代碼可以計算出cv :: stereoRectifyUncalibrated計算值的所有部分。但是,我不確定該從哪裏去從中獲取3D點雲。OpenCV StereoRectify未校準到3D點雲
我的代碼與校準版本一起工作,給我一個Q矩陣,然後用reprojectImageTo3D和StereoBM給我一個點雲。
我想比較兩種不同方法的結果,因爲有時我無法校準相機。
我有一些代碼可以計算出cv :: stereoRectifyUncalibrated計算值的所有部分。但是,我不確定該從哪裏去從中獲取3D點雲。OpenCV StereoRectify未校準到3D點雲
我的代碼與校準版本一起工作,給我一個Q矩陣,然後用reprojectImageTo3D和StereoBM給我一個點雲。
我想比較兩種不同方法的結果,因爲有時我無法校準相機。
http://blog.martinperis.com/2012/01/3d-reconstruction-with-opencv-and-point.html我認爲這會有所幫助。它具有使用PCL將視差圖轉換爲點雲的代碼,並在3D查看器中顯示。
由於您有Q,兩個圖像和其他相機參數(來自校準),您應該使用ReprojectTo3D
來獲取深度圖。
使用StereoBM
或stereoSGBM
來獲得視差圖並使用該差異圖和Q來獲得深度圖像。
StereoBM sbm;
sbm.state->SADWindowSize = 9;
sbm.state->numberOfDisparities = 112;
sbm.state->preFilterSize = 5;
sbm.state->preFilterCap = 61;
sbm.state->minDisparity = -39;
sbm.state->textureThreshold = 507;
sbm.state->uniquenessRatio = 0;
sbm.state->speckleWindowSize = 0;
sbm.state->speckleRange = 8;
sbm.state->disp12MaxDiff = 1;
sbm(g1, g2, disp); // g1 and g2 are two gray images
reprojectImageTo3D(disp, Image3D, Q, true, CV_32F);
該代碼基本上將深度圖轉換爲點雲。
pcl::PointCloud<pcl::PointXYZRGB>::Ptr point_cloud_ptr (new pcl::PointCloud<pcl::PointXYZRGB>);
double px, py, pz;
uchar pr, pg, pb;
for (int i = 0; i < img_rgb.rows; i++)
{
uchar* rgb_ptr = img_rgb.ptr<uchar>(i);
uchar* disp_ptr = img_disparity.ptr<uchar>(i);
double* recons_ptr = recons3D.ptr<double>(i);
for (int j = 0; j < img_rgb.cols; j++)
{
//Get 3D coordinates
uchar d = disp_ptr[j];
if (d == 0) continue; //Discard bad pixels
double pw = -1.0 * static_cast<double>(d) * Q32 + Q33;
px = static_cast<double>(j) + Q03;
py = static_cast<double>(i) + Q13;
pz = Q23;
// Normalize the points
px = px/pw;
py = py/pw;
pz = pz/pw;
//Get RGB info
pb = rgb_ptr[3*j];
pg = rgb_ptr[3*j+1];
pr = rgb_ptr[3*j+2];
//Insert info into point cloud structure
pcl::PointXYZRGB point;
point.x = px;
point.y = py;
point.z = pz;
uint32_t rgb = (static_cast<uint32_t>(pr) << 16 |
static_cast<uint32_t>(pg) << 8 | static_cast<uint32_t>(pb));
point.rgb = *reinterpret_cast<float*>(&rgb);
point_cloud_ptr->points.push_back (point);
}
}
point_cloud_ptr->width = (int) point_cloud_ptr->points.size();
point_cloud_ptr->height = 1;
//Create visualizer
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;
viewer = createVisualizer(point_cloud_ptr);
雖然這可能理論上回答這個問題,[這將是優選的](http://meta.stackexchange.com/q/8259),包括在這裏的答案的主要部分,並且提供的鏈接參考。 – Taryn
實際上,該鏈接具有將OpenCV視差圖轉換爲PCL點雲並以3D顯示的代碼。 – Froyo
問題是你只給了一個鏈接,如果鏈接失敗,這個答案將會過時。您應該在這裏提供鏈接,代碼等的概述,並僅包含鏈接作爲參考。 – Taryn