精华内容
下载资源
问答
  • 视觉SLAM-深蓝学院-第五讲-双目生成点云 前言 双目生成点云这道题,很多人,包括我做的时候深度都有问题。如下图。这是别人博客上的一张结果,我做的时候也是这样,仔细观察可以发现,在这里深度图的宽是原图的...

    视觉SLAM-深蓝学院-第五讲-双目生成点云

    前言

    在这里插入图片描述

    双目生成点云这道题,很多人,包括我做的时候深度都有问题。如下图。这是别人博客上的一张结果,我做的时候也是这样,仔细观察可以发现,在这里深度图的宽是原图的一半,深度图读了两次,图中间可以看到一个电线杆的形状,右边又可以看到一个电线杆。但是原深度图的长宽是没有问题的。
    在这里插入图片描述这涉及到png的交错存储问题,可以理解成隔行扫描,故问题就很明显了。解决方法有很多种:

    1. 转换png格式,改为无交错
    2. 修改程序,如下(有其他改法)
        int main(int argc, char **argv) {
            // 内参
            double fx = 718.856, fy = 718.856, cx = 607.1928, cy = 185.2157;
            // 间距
            double b = 0.573;
            // 读取图像
            cv::Mat left = cv::imread(left_file, 0);
            cv::Mat right = cv::imread(right_file, 0);
            cv::Mat disparity =
                cv::imread(disparity_file,0);  // disparty 为CV_8U,单位为像素
            // 生成点云
            vector<Vector4d, Eigen::aligned_allocator<Vector4d>> pointcloud;
            // TODO 根据双目模型计算点云
            // 如果你的机器慢,请把后面的v++和u++改成v+=2, u+=2
            for (int v = 0; v < left.rows; v++){
                for (int u = 0; u < left.cols; u++) {
                    Vector4d point(
                        0, 0, 0,
                        left.at<uchar>(v, u) / 255.0);  // 前三维为xyz,第四维为颜色
                    // start your code here (~6 lines)
                    // 根据双目模型计算 point 的位置
                    unsigned short d = disparity.at<unsigned short>(v, u/2);
                    point[2] = 200 * log(65536.0 / double(d) + 1);
                    point[0] = (u - cx) * point[2] / fx;
                    point[1] = (v - cy) * point[2] / fy;
                    pointcloud.push_back(point);
                    // end your code here
                }
            }
            // 画出点云
            showPointCloud(pointcloud);
            return 0;
        }
    

    结果

    在这里插入图片描述

    展开全文
  • 双目视差生成点云图像

    千次阅读 2018-11-25 11:33:32
    // 生成点云 vector, Eigen::aligned_allocator<Vector4d>> pointcloud; // TODO 根据双目模型计算点云 // 如果你的机器慢,请把后面的v++和u++改成v+=2, u+=2 for (int v = 0; v ; v++) for (int u = 0; u ;...

    代码如下:

    #include <opencv2/opencv.hpp>
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <string>
    #include <Eigen/Core>
    #include <pangolin/pangolin.h>
    #include <unistd.h>
    #include <pcl/io/pcd_io.h>
    
    using namespace std;
    using namespace Eigen;
    
    // 文件路径,如果不对,请调整
    string left_file = "/home/lgl/project/第四讲习题/作业题/双目视差的使用/left.png";
    string right_file = "/home/lgl/project/第四讲习题/作业题/双目视差的使用/right.png";
    string disparity_file = "/home/lgl/project/第四讲习题/作业题/双目视差的使用/disparity.png";
    
    // 在panglin中画图,已写好,无需调整
    void showPointCloud(const vector<Vector4d, Eigen::aligned_allocator<Vector4d>> &pointcloud);
    
    int main(int argc, char **argv) {
    
        // 内参
        double fx = 718.856, fy = 718.856, cx = 607.1928, cy = 185.2157;
        // 间距
        double b = 0.573;  // (注意此处的间距为双目相机左右光圈的间距)
    
        // 读取图像
        cv::Mat left = cv::imread(left_file, 0);
        cv::Mat right = cv::imread(right_file, 0);
        cv::Mat disparity = cv::imread(disparity_file, 0); // disparty 为CV_8U,单位为像素
        if(left.data)
            cout<<"loaded left.png"<<endl;
        cv::imshow("left",left);
        cv::imshow("right",right);
        cv::imshow("disparity",disparity);
        cv::waitKey(0);
        cv::destroyAllWindows();
    
        // 生成点云
        vector<Vector4d, Eigen::aligned_allocator<Vector4d>> pointcloud;
    
        // TODO 根据双目模型计算点云
        // 如果你的机器慢,请把后面的v++和u++改成v+=2, u+=2
        for (int v = 0; v < left.rows; v++)
            for (int u = 0; u < left.cols; u++) {
    
                Vector4d point(0, 0, 0, left.at<uchar>(v, u) / 255.0); // 前三维为xyz,第四维为颜色
    
                // start your code here (~6 lines)
                // 根据双目模型计算 point 的位置
                unsigned int d=disparity.ptr<unsigned short>(v)[u];
                if(d==0)
                {
                    cout<<"d==0"<<endl;
                    continue;
                }
                point[2]=(fx*b*1000)/d;
                point[1]=(v-cy)*point[2]/fy;
                point[0]=(u-cx)*point[2]/fx;
                cout<<"point = [ "<<point[0]<<" "<<point[1]<<" "<<point[2]<<" "<<point[3]<<" ]"<<endl;
                pointcloud.push_back(point);
                // end  your code here
            }
    
        cout<<"点云共有 : "<<pointcloud.size()<<"个点"<<endl;
        // 画出点云
        showPointCloud(pointcloud);
        return 0;
    }
    
    void showPointCloud(const vector<Vector4d, Eigen::aligned_allocator<Vector4d>> &pointcloud) {
    
        if (pointcloud.empty()) {
            cerr << "Point cloud is empty!" << endl;
            return;
        }
    
        pangolin::CreateWindowAndBind("Point Cloud Viewer", 1024, 768);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
        pangolin::OpenGlRenderState s_cam(
                pangolin::ProjectionMatrix(1024, 768, 500, 500, 512, 389, 0.1, 1000),
                pangolin::ModelViewLookAt(0, -0.1, -1.8, 0, 0, 0, 0.0, -1.0, 0.0)
        );
    
        pangolin::View &d_cam = pangolin::CreateDisplay()
                .SetBounds(0.0, 1.0, pangolin::Attach::Pix(175), 1.0, -1024.0f / 768.0f)
                .SetHandler(new pangolin::Handler3D(s_cam));
    
        while (pangolin::ShouldQuit() == false) {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
            d_cam.Activate(s_cam);
            glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    
            glPointSize(2);
            glBegin(GL_POINTS);
            for (auto &p: pointcloud) {
                glColor3f(p[3], p[3], p[3]);
                glVertex3d(p[0], p[1], p[2]);
            }
            glEnd();
            pangolin::FinishFrame();
            usleep(5000);   // sleep 5 ms
        }
        return ;
    }
    
    展开全文
  • OpenCV 双目视差图生成点云变成这样 双目视差图生成点云变成这样,大家知道怎么回事吗 校正图像与视差图

    OpenCV 双目视差图生成点云变成这样

    双目视差图生成点云变成这样,大家知道怎么回事吗

    校正图像与视差图

    展开全文
  • // 生成点云:一起一个容器对象pointcloud,其元素是四维向量 //当vector中元素是Eigen中的类型的时候,必须调用Eigen::aligned_allocator分配内存空间,否则编译不会报错,运行会报错 //而内置类型则不用,如...

    一、CMakeLists文件

    cmake_minimum_required(VERSION 3.15)
    project(stereoVision)
    find_package(Pangolin REQUIRED)
    find_package(OpenCV REQUIRED)
    
    include_directories(${OpenCV_INCLUDE_DIRS})
    include_directories(${Pangolin_INCLUDE_DIRS})
    
    set(CMAKE_CXX_STANDARD 14)
    
    add_executable(stereoVision main.cpp)
    target_link_libraries(stereoVision ${OpenCV_LIBS} ${Pangolin_LIBRARIES})
    

    二、.cpp文件

    #include <opencv2/opencv.hpp>
    //容器vector的头文件,vector是可以存放任意类型的动态数组
    #include <vector>
    #include <string>
    #include <Eigen/Core>
    //用于显示3D视觉图像
    #include <pangolin/pangolin.h>
    //Linux系统服务头文件
    #include <unistd.h>
    
    using namespace std;
    using namespace Eigen;
    
    // 文件路径
    string left_file = "/home/zhangman/slambook2-master/ch5/stereo/left.png";
    string right_file = "/home/zhangman/slambook2-master/ch5/stereo/right.png";
    
    // 函数声明,在pangolin中画图,已写好,无需调整
    void showPointCloud(
            const vector<Vector4d, Eigen::aligned_allocator<Vector4d>> &pointcloud);
    
    int main(int argc, char **argv) {
    
        // 内参
        double fx = 718.856, fy = 718.856, cx = 607.1928, cy = 185.2157;
        // 基线
        double b = 0.573;
    
        // 读取左右目图像
        cv::Mat left = cv::imread(left_file, 0);
        cv::Mat right = cv::imread(right_file, 0);
        //创建一个指针,指向OPenCV中的sgbm(半全局立体匹配算法),其中最小视差为0,最大视差为96
        cv::Ptr<cv::StereoSGBM> sgbm = cv::StereoSGBM::create(
                0, 96, 9, 8 * 9 * 9, 32 * 9 * 9, 1, 63, 10, 100, 32);    // 神奇的参数
        //定义CV_32F格式视差图disparity,定义sgbm算法输出是插图disparity_sgbm
        //CV_32F格式在下面转换的时候指定,该格式像素为0-1.0之间的任意float类型数,是一些数值计算要求的格式
        cv::Mat disparity_sgbm, disparity;
        //调用sgbm算法计算左右目图像视差,视差图输出到disparity中
        sgbm->compute(left, right, disparity_sgbm);
        //将disparity_sgbm转换成CV_32F类型图像,存储在disparity中,第三个参数代表尺度的变化
        //CV_32F是浮点型的-像素可以有0-1.0之间的任何值,这对于数据的某些计算集很有用,但必须将其转换为8位以保存或显示,方法是将每个像素乘以255。
        disparity_sgbm.convertTo(disparity, CV_32F);
        cout<<disparity.at<float>(100,100);
        //将sgbm输出的图像矩阵转化为CV_32F,并缩小像素值为1/16(这个缩小倍数应该和sgbm算法有关),缩小后的像素范围为0-96
        disparity_sgbm.convertTo(disparity, CV_32F, 1.0/16.0f);
        // 生成点云:一起一个容器对象pointcloud,其元素是四维向量
        //当vector中元素是Eigen中的类型的时候,必须调用Eigen::aligned_allocator<>分配内存空间,否则编译不会报错,运行会报错
        //而内置类型则不用,如vector<int> a;定义一个名字为a的动态数组,数组元素类型为int
        vector<Vector4d, Eigen::aligned_allocator<Vector4d>> pointcloud;
    
        // 遍历元素
        for (int v = 0; v < left.rows; v++)
            for (int u = 0; u < left.cols; u++) {
                //如果视差不在最大视差与最小视差之间,就不考察这个点
                if (disparity.at<float>(v, u) <= 0.0 || disparity.at<float>(v, u) >= 96.0) continue;
    
                //创建一个四维向量用于存储一个三维点的信息,前三维为xyz
                // 第四维为颜色,这里采用原始图像颜色作为参考,显示效果更好,并对颜色做了归一化处理
                Vector4d point(0, 0, 0, right.at<uchar>(v, u) / 255.0);
                // 根据双目模型计算 point 的三维空间位置
                double x = (u - cx) / fx;
                double y = (v - cy) / fy;
                double depth = fx * b / (disparity.at<float>(v, u));
                point[0] = x * depth;
                point[1] = y * depth;
                point[2] = depth;
    
                //将计算得到的三维点从尾部添加到点云容器point中
                pointcloud.push_back(point);
            }
    
        //显示视差图,对视差图中所有像素灰度值除以96,从而将像素值归一化到0-1,符合CV_32F格式条件,并显示
        cv::imshow("disparity", disparity / 96.0);
        cv::waitKey(0);
        // 画出点云
        showPointCloud(pointcloud);
        return 0;
    }
    
    //使用pangolin绘制点云图函数
    void showPointCloud(const vector<Vector4d, Eigen::aligned_allocator<Vector4d>> &pointcloud) {
    
        //如果点云是空的,不绘制
        if (pointcloud.empty()) {
            cerr << "Point cloud is empty!" << endl;
            return;
        }
    
        //创建并初始化显示窗口,定义窗口名称,宽度,高度
        pangolin::CreateWindowAndBind("Point Cloud Viewer", 1024, 768);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
        pangolin::OpenGlRenderState s_cam(
                pangolin::ProjectionMatrix(1024, 768, 500, 500, 512, 389, 0.1, 1000),
                pangolin::ModelViewLookAt(0, -0.1, -1.8, 0, 0, 0, 0.0, -1.0, 0.0)
        );
    
        pangolin::View &d_cam = pangolin::CreateDisplay()
                .SetBounds(0.0, 1.0, pangolin::Attach::Pix(175), 1.0, -1024.0f / 768.0f)
                .SetHandler(new pangolin::Handler3D(s_cam));
    
        while (pangolin::ShouldQuit() == false) {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
            d_cam.Activate(s_cam);
            glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    
            glPointSize(2);
            glBegin(GL_POINTS);
            //如果想绘制其他图像,将这里的pointcloud改成对应的容器就可以
            //或者将pointcloud对应到其他图像
            for (auto &p: pointcloud) {
                glColor3f(p[3], p[3], p[3]);
                glVertex3d(p[0], p[1], p[2]);
            }
            glEnd();
            pangolin::FinishFrame();
            usleep(5000);   // sleep 5 ms
        }
        return;
    }
    
    
    展开全文
  • 使用 Matlab 生成双目视差及点云图像

    千次阅读 2020-06-05 21:22:20
    使用 Matlab 生成双目视差及点云图像 准备工作 采集棋盘格图像 使用 Matlab Stereo Camera Calibrator 进行双目相机标定 编写 matlab 脚本,生成视差图,点云图(TODO) 使用 Matlab 生成双目视差及点云图像...
  • 主要利用高博书中第5讲相机模型的知识解决相机畸变校正和双目点云生成的问题
  • ELAS是一种基于概率模型的有效立体匹配算法,能够给予双目图像生成深度图,进而转化为点云.该算法的一种改进算法为LS-ELAS,其论文发表在2017年ICRA上,文章题目为"LS-ELAS: Line Segment based Efficient Large Scale ...
  • 双目矫正+测距+深度图+点云

    千次阅读 热门讨论 2020-06-01 20:56:36
    因为只有一个视角的深度图,所以生成的点云图很粗糙只有个轮廓,顶多算是稀疏原始点云。还需要后期点云滤波、多点云拼接。至于为什么会有对称的两个轮廓,我觉得可能生成了左右两个视角的点云图,还有我的相机参数不...
  • 相机模型和双目立体匹配
  • 一、双目三维重建(binocular stereo):输入左右两张图片 二、SFM(Structure from Motion)运动推断结构:一系列不同视角图片 三、MVS(Multi View ...5、深度图生成点云图(点云质量的好坏与视差图的质量密切相关
  • 本帖最后由 newly1429 于 2020-8-31 19:23 编辑本人在做双目人脸三维重建,MATLAB版本R2016a,因为disparitySGM函数在2016里用不了,特地下了个R2020a相机标定是自己用程序生成一张棋盘格打印出来贴在板子上,然后用...
  • AI学习笔记之三维计算机视觉与点云模型立体视觉立体视觉的概念立体视觉的原理单目系统双目系统和视差对极几何约束SIFTsift特征的特点sift算法总体介绍sift特征提取和匹配具体步骤1、生成高斯差分金字塔(DOG金字塔)...
  • 在用双目摄像头进行视觉测距、识别时,会经常用到点云格式,PointCloud2格式的数据.我们将PointCloud2转化成costmap_2d,生成珊格地图。然后进行路径规划等操作。在实际测试时,由于PointCloud2的点云格式太大,懂则几...
  • 第六十六篇:单目三维重建点云

    千次阅读 2016-12-15 20:42:56
    区别在于:单目需要每次计算得到重建图像之间旋转和平移之间的关系(RT),三维的生成部分不是像双目通过校正后的图使用SAD等方法得到的时差的的,是通过基于匹配点的三角化计算得到的,相比双目来说,过程更加复杂...
  • 各位好,最近在学习双目立体视觉的相关知识,有没有大神能讲解一下利用双目相机的原始图、生成的视差图和相机内参生成点云的方法和 demo code,还有我在利用BM算法生成的深度图用照片查看器无法打开,提示无效的位图...
  • 双目视觉利用两幅图像进行特征点匹配,生成三维点云,完成三维重建
  • Visual Studio 2017 双目开发 Visual Studio 2017 双目开发项目主要包含下面几个方法: opencv及PCL配置 MSRA-OpenPAI介绍及配置 调用摄像头及图片分隔 opencv及流处理分割 ...深度图生成点云 待续 ...
  • Visual Studio 2017 双目开发 Visual Studio 2017 双目开发项目主要包含下面几个方法: opencv及PCL配置 MSRA-OpenPAI介绍及配置 调用摄像头及图片分隔 opencv及流处理分割 ...深度图生成点云 待续 ...
  • Visual Studio 2017 双目开发 Visual Studio 2017 双目开发项目主要包含下面几个方法: opencv及PCL配置 MSRA-OpenPAI介绍及配置 调用摄像头及图片分隔 opencv及流处理分割 ...深度图生成点云 待续 ...
  • Visual Studio 2017 双目开发 Visual Studio 2017 双目开发项目主要包含下面几个方法: opencv及PCL配置 ...深度图生成点云 待续 opencv介绍及下载  OpenCV的全称是Open Source Computer Vision ...
  • 首先, 采用SFM算法通过双目相机在目标周围拍摄n组图像对, 在每组双目图像对中手动选取目标的初始匹配特征点, 计算其三维坐标, 生成n组三维点云; 接着, 通过ICP算法计算并优化n组三维点云之间的旋转矩阵与平移向量...
  • 通过双目相机生成不同位姿下的目标物体点云以便快速提取靶标角点的世界坐标,不同于常用的点云配准位姿估计,本文取对应点坐标差的均值表示平移向量;然后,求取靶标角点所在切面的法向量,组成目标在不同位姿坐标系下的...
  • 三维重建 有了上述的视差图,我们就可以来获取物体的点云了,同样的这里利用了opencv2中...通过create_output函数来生成一个点云数据.ply create_output(output_points, output_colors, output_file) 运行结果: ...

空空如也

空空如也

1 2
收藏数 38
精华内容 15
关键字:

双目生成点云