Can you help me to convert Stereo map to 3d point cloud?

asked 2018-09-07 16:35:37 -0600

These are original pictures from two cameras. image description image description

Then I do the calibration and use SGBM method to get the depth map.

image description

I think this isn't a good enough result. But it should generate a point cloud. ps: I use wlsfilter to get a better result. image description

I can't get a good 3d point cloud. I get something like the following picture[in meshlab]. I can't distinguish anything from the point cloud.

image description

This is the xyzcloud file. xyzcloud

    cv::Ptr<cv::StereoSGBM> sgbm = cv::StereoSGBM::create(0, 16, 3);
    int numberOfDisparities = 64;
    int SADWindowSize = 7;
    numberOfDisparities = numberOfDisparities > 0 ? numberOfDisparities : ((img_l.cols / 8) + 15) & -16;

    sgbm->setPreFilterCap(63);
    int sgbmWinSize = SADWindowSize > 0 ? SADWindowSize : 3;
    sgbm->setBlockSize(sgbmWinSize);

    int cn = img_l.channels();

    sgbm->setP1(8 * cn*sgbmWinSize*sgbmWinSize);
    sgbm->setP2(32 * cn*sgbmWinSize*sgbmWinSize);
    sgbm->setMinDisparity(0);
    sgbm->setNumDisparities(numberOfDisparities);
    sgbm->setUniquenessRatio(10);
    sgbm->setSpeckleWindowSize(100);
    sgbm->setSpeckleRange(32);
    sgbm->setDisp12MaxDiff(1);
    sgbm->setMode(cv::StereoSGBM::MODE_SGBM);
     cv::Mat disp, disp8, disp32;
    int64 t = cv::getTickCount();
    sgbm->compute(img_l, img_r, disp);

    disp.convertTo(disp8, CV_8U, 255/(numberOfDisparities*16.));

    cv::imshow("disp8", disp8);



    cv::Mat out;

    cv::reprojectImageTo3D(disp, out, Q, true);
    out = out.mul(0.1);

    cv::Mat depth;
    cv::extractChannel(out, depth, 2);
    cv::Mat output;
    output = 255 - depth * 255 / 10;

    output.convertTo(output, CV_8UC1);
    cv::applyColorMap(output, output, cv::COLORMAP_JET);

    cv::Mat img_l_color;
    cv::cvtColor(img_l, img_l_color, cv::COLOR_GRAY2BGR);


    cv::Mat points;
    points = out;
    std::cout<<out.size()<<std::endl<<out.channels();
    std::ofstream point_cloud_file;
    point_cloud_file.open ("point_cloud.xyz");
    for(int i = 0; i < points.rows; i++) {
         for(int j = 0; j < points.cols; j++) {
             if(points.at<cv::Vec3f>(i,j)[2] < 10) {
                    point_cloud_file << points.at<cv::Vec3f>(i,j)[0] << " " << points.at<cv::Vec3f>(i,j)[1] << " " << points.at<cv::Vec3f>(i,j)[2]<< " " << static_cast<unsigned>(img_l_color.at<uchar>(i,j)) << " " << static_cast<unsigned>(img_l_color.at<uchar>(i,j))<<" "<<static_cast<unsigned>(img_l_color.at<uchar>(i,j))<<std::endl;
             }
         }
    }
     point_cloud_file.close();
    t = cv::getTickCount() - t;
edit retag flag offensive close merge delete