• ELAS库计算双目视差图


    ELAS源码下载:https://www.cvlibs.net/download.php?file=libelas.zip
    代码结构目录
    在这里插入图片描述
    修改/src/main.cpp如下:

    /*
    Copyright 2011. All rights reserved.
    Institute of Measurement and Control Systems
    Karlsruhe Institute of Technology, Germany
    
    This file is part of libelas.
    Authors: Andreas Geiger
    
    libelas is free software; you can redistribute it and/or modify it under the
    terms of the GNU General Public License as published by the Free Software
    Foundation; either version 3 of the License, or any later version.
    
    libelas is distributed in the hope that it will be useful, but WITHOUT ANY
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
    PARTICULAR PURPOSE. See the GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License along with
    libelas; if not, write to the Free Software Foundation, Inc., 51 Franklin
    Street, Fifth Floor, Boston, MA 02110-1301, USA 
    */
    
    // Demo program showing how libelas can be used, try "./elas -h" for help
    
    #include 
    #include "elas.h"
    #include "image.h"
    #include
    #include
    #include
    #include
    #include
    #include "opencv2/imgproc/imgproc_c.h"
    
    using namespace std;
    
    // compute disparities of pgm image input pair file_1, file_2
    void process (const char* file_1,const char* file_2) {
    
      cout << "Processing: " << file_1 << ", " << file_2 << endl;
    
      // load images
      image *I1,*I2;
      I1 = loadPGM(file_1);
      I2 = loadPGM(file_2);
    
      // check for correct size
      if (I1->width()<=0 || I1->height() <=0 || I2->width()<=0 || I2->height() <=0 ||
          I1->width()!=I2->width() || I1->height()!=I2->height()) {
        cout << "ERROR: Images must be of same size, but" << endl;
        cout << "       I1: " << I1->width() <<  " x " << I1->height() << 
                     ", I2: " << I2->width() <<  " x " << I2->height() << endl;
        delete I1;
        delete I2;
        return;    
      }
    
      // get image width and height
      int32_t width  = I1->width();
      int32_t height = I1->height();
    
      // allocate memory for disparity images
      const int32_t dims[3] = {width,height,width}; // bytes per line = width
      float* D1_data = (float*)malloc(width*height*sizeof(float));
      float* D2_data = (float*)malloc(width*height*sizeof(float));
    
      // process
      Elas::parameters param;
      param.postprocess_only_left = false;
      Elas elas(param);
      elas.process(I1->data,I2->data,D1_data,D2_data,dims);
    
      // find maximum disparity for scaling output disparity images to [0..255]
      float disp_max = 0;
      for (int32_t i=0; idisp_max) disp_max = D1_data[i];
        if (D2_data[i]>disp_max) disp_max = D2_data[i];
      }
    
      // copy float to uchar
      image *D1 = new image(width,height);
      image *D2 = new image(width,height);
      for (int32_t i=0; idata[i] = (uint8_t)max(255.0*D1_data[i]/disp_max,0.0);
        D2->data[i] = (uint8_t)max(255.0*D2_data[i]/disp_max,0.0);
      }
    
      // save disparity images
      char output_1[1024];
      char output_2[1024];
      strncpy(output_1,file_1,strlen(file_1)-4);
      strncpy(output_2,file_2,strlen(file_2)-4);
      output_1[strlen(file_1)-4] = '\0';
      output_2[strlen(file_2)-4] = '\0';
      strcat(output_1,"_disp.pgm");
      strcat(output_2,"_disp.pgm");
      savePGM(D1,output_1);
      savePGM(D2,output_2);
    
      // free memory
      delete I1;
      delete I2;
      delete D1;
      delete D2;
      free(D1_data);
      free(D2_data);
    }
    
    int main (int argc, char** argv) {
    
      // run demo
      if (argc==2 && !strcmp(argv[1],"demo")) {
        process("img/cones_left.pgm",   "img/cones_right.pgm");
        process("img/aloe_left.pgm",    "img/aloe_right.pgm");
        process("img/raindeer_left.pgm","img/raindeer_right.pgm");
        process("img/urban1_left.pgm",  "img/urban1_right.pgm");
        process("img/urban2_left.pgm",  "img/urban2_right.pgm");
        process("img/urban3_left.pgm",  "img/urban3_right.pgm");
        process("img/urban4_left.pgm",  "img/urban4_right.pgm");
        cout << "... done!" << endl;
    
      // compute disparity from input pair
      } else if (argc==3) {
    
    
        string argv1 = string(argv[1]);
        string argv2 = string(argv[2]);
        string extension1 = argv1.substr(argv1.find_last_of('.'), argv1.length());
        string extension2 = argv1.substr(argv2.find_last_of('.'), argv2.length());
    
        if (extension1 == ".pgm" || extension2 == ".pgm")
        {
          process(argv[1],argv[2]);
          cout << "... done!" << endl;
    
          string name = argv1.substr(argv1.find_last_of('/')+1, argv1.length());
          name = name.substr(0, name.find_last_of('.')) + "_disp";
    
          cv::Mat img = cv::imread("../img/" + name + ".pgm");
          cv::normalize(img, img, 0, 255, cv::NORM_MINMAX);
          cv::imshow("Disp Image window",img);
          cv::waitKey(0);
          cv::imwrite("../img/" + name + ".png", img);
    
        }
        else if (extension1 == ".png" || extension2 == ".png")
        {
          //参考:https://blog.csdn.net/dulingwen/article/details/104128503
          cv::Mat left = cv::imread(argv[1]);
          cv::Mat right = cv::imread(argv[2]);
          // cv::imshow("Left Image",left);
          // cv::imshow("Right Image",right);
          // cv::waitKey(0);
          if (left.size != right.size) 
          {
            cerr << "左右视图必须拥有相同的尺寸" << endl;
            return -1;
          }
          if (left.channels() == 3)
          cvtColor(left, left, cv::COLOR_RGB2GRAY);
    	    if (right.channels() == 3)
          cvtColor(right, right, cv::COLOR_RGB2GRAY);
    
          int width = left.cols;
          int height = left.rows;
          int dim[3] = { width, height, width };
        
          cv::Mat disp_left = cv::Mat::zeros(cv::Size(width, height), CV_32FC1);
          cv::Mat disp_right = cv::Mat::zeros(cv::Size(width, height), CV_32FC1);
        
          // 参数设置	
          Elas::parameters param;
          param.disp_min = 0;                                     // 最小视差	
          param.disp_max = 256;                                // 最大视差	
          param.support_threshold = 0.85;              // 比率测试:最低match VS 次低match
          param.support_texture = 10;                     // 支持点的最小纹理
          param.candidate_stepsize = 5;                  // 用于支持点的sobel特征匹配的邻域半径
          param.incon_window_size = 5;                  // 不连续性窗口的尺寸
          param.incon_threshold = 5;                       // 不连续性窗口内的视差范围阈值
          param.incon_min_support = 5;                 // 不连续性窗口内的最低支持点数量
          param.add_corners = true;                        // 是否添加角点
          param.grid_size = 20;                                  // 网格尺寸
          param.beta = 0.02;                                      // 图像相似性度量的参数
          param.gamma = 3;                                      // 先验概率常数
          param.sigma = 1;                                         // 先验概率的标准差
          param.sradius = 3;                                       // 标准差半径
          param.match_texture = 1;                         // 最低纹理
          param.lr_threshold = 1;                             // 左右一致性检验阈值
          param.speckle_sim_threshold = 1;          // 连通域判断阈值
          param.speckle_size = 200;                        // 连通域噪声尺寸判断阈值
          param.ipol_gap_width = 3;                       // 空洞宽
          param.filter_median = false;                     // 是否中值滤波
          param.filter_adaptive_mean = true;        // 是否自适应中值滤波
          param.postprocess_only_left = true;     // 是否只对左视差图后处理,设置为True可以节省时间
          param.subsampling = false;                     // 每个两个像素进行视差计算,设置为True可以节省时间,但是传入的D1和D2的分辨率必须为(w/2) x (h/2)
        
          clock_t start = clock();
          Elas elas(param);
          elas.process(left.data, right.data, disp_left.ptr(0), disp_right.ptr(0), dim);
          clock_t end = clock();
          cout << "running time: " << (double)(1000 * (end - start) / CLOCKS_PER_SEC) << endl;
        
          disp_left = disp_left * 3;
    
          string name = argv1.substr(argv1.find_last_of('/')+1, argv1.length());
          name = name.substr(0, name.find_last_of('.')) + "_disp";
          cout << "../img/" + name + ".png" << endl;
          cv::imwrite("../img/" + name + ".png", disp_left);
          cout << "... done!" << endl;
    
        }
    
      // display help
      } else {
        cout << endl;
        cout << "ELAS demo program usage: " << endl;
        cout << "./elas demo ................ process all test images (image dir)" << endl;
        cout << "./elas left.pgm right.pgm .. process a single stereo pair" << endl;
        cout << "./elas -h .................. shows this help" << endl;
        cout << endl;
        cout << "Note: All images must be pgm greylevel images. All output" << endl;
        cout << "      disparities will be scaled such that disp_max = 255." << endl;
        cout << endl;
      }
    
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226

    打开终端

    cd ~/Documents/projects/libelas/
    mkdir build
    cd /build
    cmake ..
    make
    
    • 1
    • 2
    • 3
    • 4
    • 5

    编译通过后

    # 输入pgm格式图片得到的视差图
    ./elas ../img/cones_left.pgm ../img/cones_right.pgm
    
    • 1
    • 2

    输入pgm格式图片得到的视差图

    # 输入png格式图片得到的视差图
    ./elas ~/Documents/data/MyEuRoC/cam0/data/1694603839467.png ~/Documents/data/MyEuRoC/cam1/data/1694603839467.png 
    
    • 1
    • 2

    请添加图片描述

    参考:
    [1] 双目立体匹配算法:ELAS
    [2] VS2019下cmake项目:利用ELAS方法计算双目视差

  • 相关阅读:
    【机器学习与实现】kNN分类算法示例
    【博客550】k8s乐观锁机制:控制并发请求与数据一致性
    android-适配方案-密度适配-最小宽度限定符
    wpf devexpress添加TreeListControl到项目
    学术报告系列(六) - Autonomous Driving on the journey to full autonomy
    【Mysql】Mysql的启动选项和系统变量(二)
    Linux 服务器下 pypy 下载数据集
    postgresql源码学习(34)—— 事务日志⑩ - 全页写机制
    基于JAVA旅游足迹记录系统计算机毕业设计源码+数据库+lw文档+系统+部署
    字符串算术表达式求值-简单计算器实现(栈)-数据结构和算法(Java)
  • 原文地址:https://blog.csdn.net/weixin_41631106/article/details/132882417