1

cv::stereoRectifyUncalibratedで値を計算するまでのすべての部分を実行するコードがいくつかあります。ただし、そこから3Dポイントクラウドを取得するためにそこからどこに行くべきかわかりません。

Qマトリックスを提供するキャリブレーション済みバージョンで動作するコードがあり、それをreprojectImageTo3DおよびStereoBMで使用して、ポイントクラウドを提供します。

カメラのキャリブレーションができない場合があるため、2つの異なる方法の結果を比較したいと思います。

4

1 に答える 1

1

http://blog.martinperis.com/2012/01/3d-reconstruction-with-opencv-and-point.htmlこれは参考になると思います。PCL を使用して視差画像を点群に変換し、3D ビューアーに表示するコードがあります。

Q、2 つの画像、およびその他のカメラ パラメータ (キャリブレーションから) があるためReprojectTo3D、深度マップを取得するために使用する必要があります。

StereoBMまたはを使用stereoSGBMして Disparity Map を取得し、その Disparit Map と 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 );
于 2013-03-19T15:01:09.453 に答える