用VS+Opencv3.1从双目立体视差图中重建三维点云


转载请注明原创出处:http://blog.csdn.net/u014283958/


基本原理

详细原理请阅读这篇文章http://www.360doc.com/content/14/0205/15/10724725_349968116.shtml.

用VS+Opencv3.1从双目立体视差图中重建三维点云_第1张图片

基本流程

用VS+Opencv3.1从双目立体视差图中重建三维点云_第2张图片

代码

本代码运行需要在VS上配置好opencv3.1+openNI+PCL,opencv3.1的配置可以在网上找到很多资料,openNI和PCL的配置可以参看上一篇博文下http://blog.csdn.net/u014283958/article/details/52599457
下面是代码:

//by shuishui shiwenjun 20160926
#include 
#include   
#include   
#include   
#include   

using namespace cv;
using namespace std;
using namespace pcl;

int user_data;
//相机内参,根据输入改动
const double u0 = 1329.49 / 4;//由于后面resize成原图的1/4所以有些参数要缩小相同倍数
const double v0 = 954.485 / 4;
const double fx = 6872.874 / 4;
const double fy = 6872.874 / 4;
const double Tx = 174.724;
const double doffs = 293.97 / 4;

void viewerOneOff(visualization::PCLVisualizer& viewer)
{
    viewer.setBackgroundColor(0.0, 0.0, 0.0);
}

int main()
{
    PointCloud cloud_a;
    PointCloud::Ptr cloud(new PointCloud);



    Mat color1 = imread("im0.png");
    Mat depth = imread("Sword1_perfect_d.png");
    ////Resize
    //color1.resize();
    Mat color;
    resize(color1, color, Size(color1.cols/4,color1.rows/4), 0, 0, CV_INTER_LINEAR);
    //imshow("h",color);
    //waitKey(0);

    int rowNumber = color.rows;
    int colNumber = color.cols;

    cloud_a.height = rowNumber;
    cloud_a.width = colNumber;
    cloud_a.points.resize(cloud_a.width * cloud_a.height);

    for (unsigned int u = 0; u < rowNumber; ++u)
    {
        for (unsigned int v = 0; v < colNumber; ++v)
        {
            /*unsigned int num = rowNumber*colNumber-(u*colNumber + v)-1;*/
            unsigned int num = u*colNumber + v;
            double Xw = 0, Yw = 0, Zw = 0;


            Zw = fx*Tx / (((double)depth.at(u, v)[0]) + doffs);
            Xw = (v+1 - u0) * Zw / fx;
            Yw = (u+1 - v0) * Zw / fy;

            cloud_a.points[num].b = color.at(u, v)[0];
            cloud_a.points[num].g = color.at(u, v)[1];
            cloud_a.points[num].r = color.at(u, v)[2];

            cloud_a.points[num].x = Xw;
            cloud_a.points[num].y = Yw;
            cloud_a.points[num].z = Zw;
        }
    }

    *cloud = cloud_a;

    visualization::CloudViewer viewer("Cloud Viewer");

    viewer.showCloud(cloud);

    viewer.runOnVisualizationThreadOnce(viewerOneOff);

    while (!viewer.wasStopped())
    {
        user_data = 9;
    }

    return 0;
}

效果图

输入:
“im0.png”可以从http://vision.middlebury.edu/stereo/data/scenes2014/datasets/Sword1-perfect/im0.png 下载;

“Sword1_perfect_d.png”
用VS+Opencv3.1从双目立体视差图中重建三维点云_第3张图片

输出:
点云截图1
用VS+Opencv3.1从双目立体视差图中重建三维点云_第4张图片
点云截图2
用VS+Opencv3.1从双目立体视差图中重建三维点云_第5张图片
点云截图3
用VS+Opencv3.1从双目立体视差图中重建三维点云_第6张图片


你可能感兴趣的:(三维重建,opencv,PCL,opencv,visual,studio,stereo)