У меня есть некоторый код, который обрабатывает все части вплоть до вычисления значений с помощью cv :: stereoRectifyUncalibrated. Однако я не уверен, куда идти, чтобы получить облако 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 );
Других решений пока нет …