ELAS库计算双目视差图

ELAS源码下载:https://www.cvlibs.net/download.php?file=libelas.zip
代码结构目录
ELAS库计算双目视差图_第1张图片
修改/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;
}

打开终端

cd ~/Documents/projects/libelas/
mkdir build
cd /build
cmake ..
make

编译通过后

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

ELAS库计算双目视差图_第2张图片

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

ELAS库计算双目视差图_第3张图片

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

你可能感兴趣的:(三维重建,立体匹配,双目视觉)