SGM代码及其测试代码和结果

SGM代码

github上边已经有很多开源的SGM代码了,下面就给出几个已经试过好用的代码,以免忘记下载的代码来自哪个连接。

  • gishi523 /semi-global-matching :基于CSCT的SGM,用左右一致性检测、唯一性检测、中值滤波进行后处理,并且用SSE4.1 and OpenMP进行优化,大概 10 fps / s。
  • dhernandez0 /sgm :《Embedded real-time stereo estimation via Semi-Global Matching on the GPU, D. Hernandez-Juarez》这篇文章的实现,用GPU进行加速,是源码不是库,很有参考价值。在Kitti上边跑是64 fps /s。
  • reisub /SemiGlobal-Matching :基于BT的SGM,没有任何的后处理,速度较慢,跑一帧需要17s。
  • ethan-li-coding /SemiGlobalMatching :李博的代码,基于CT的SGM,用左右一致性检测,唯一性检测,亚像素插值,在CPU上实现,在vs2019上release跑大概 1 fps / s。
  • fixstars /libSGM :基于GPU的SGM,代码写成库了,写的非常乱,没什么参考价值,但速度确实挺快,在KITTI跑 50fps/s。

测试代码

#include 
#include 
#include 

using namespace std;
using namespace cv;

int main(int argc, char** argv) {

    cv::Mat GT;
    cv::Mat output_disparity;
    Mat occl,occ_and_discont,occ_and_textl;
    GT = cv::imread("/home/dcm/图片/2003/teddy/disp2.png", CV_LOAD_IMAGE_GRAYSCALE);
    output_disparity = cv::imread("/home/dcm/semi-global-matching-master/build/output_disparity.png", CV_LOAD_IMAGE_GRAYSCALE);
    occl = imread("/home/dcm/图片/2003/teddy/occl.png",CV_LOAD_IMAGE_GRAYSCALE);
    occ_and_discont = imread("/home/dcm/图片/2003/teddy/occ_and_discont.png",CV_LOAD_IMAGE_GRAYSCALE);
    occ_and_textl = imread("/home/dcm/图片/2003/teddy/occ_and_textl.png",CV_LOAD_IMAGE_GRAYSCALE);

    if (!GT.data || !output_disparity.data || !occl.data || !occ_and_discont.data || !occ_and_textl.data) {
        std::cerr <<  "Could not open or find one of the images!" << std::endl;
        return -1;
    }

    if (GT.rows != output_disparity.rows || GT.cols != output_disparity.cols || GT.rows != occl.rows || GT.cols != occl.cols
     || GT.rows != occ_and_discont.rows || GT.cols != occ_and_discont.cols || GT.rows != occ_and_textl.rows
     || GT.cols != occ_and_textl.cols) {
        std::cerr << "Error: The images have different dimensions!" << std::endl;
        return -2;
    }

    unsigned long all, nonoccl, discont, textl;
    unsigned long all_counter, nonoccl_counter, discont_counter, textl_counter;
    all = nonoccl = discont = textl = all_counter = nonoccl_counter = discont_counter = textl_counter = 0;
    for (int row = 0; row < GT.rows; ++row) {
        for (int col = 0; col < GT.cols; ++col) {
            //统计总体的误匹配率
            if(GT.at<uchar>(row, col) != 0){
                all_counter++;
                if(abs(GT.at<uchar>(row, col) - output_disparity.at<uchar>(row, col)) > 4){
                    all++;
                }
            }
            //统计非遮挡的误匹配率
            if(occl.at<uchar>(row, col) != 0){
                nonoccl_counter++;
                if(abs(GT.at<uchar>(row, col) - output_disparity.at<uchar>(row, col)) > 4){
                    nonoccl++;
                }
            }
            //统计深度不连续的误匹配率
            if(occ_and_discont.at<uchar>(row, col) == 255){
                discont_counter++;
                if(abs(GT.at<uchar>(row, col) - output_disparity.at<uchar>(row, col)) > 4){
                    discont++;
                }
            }
            //统计无纹理的误匹配率
            if(occ_and_textl.at<uchar>(row, col) == 255){
                textl_counter++;
                if(abs(GT.at<uchar>(row, col) - output_disparity.at<uchar>(row, col)) > 4){
                    textl;
                }
            }

        }
    }
    cout<<"rows * cols = "<<GT.rows*GT.cols<<endl;
    cout<<"all_counter = "<<all_counter<<endl;
    cout<<"all = "<<all<<endl;
    cout<<"ALL errer: ";
    std::cout << 100 * double(all / double(all_counter)) << "%"<<endl;
    cout<<endl;

    cout<<"nonoccl_counter = "<<nonoccl_counter<<endl;
    cout<<"nonoccl = "<<nonoccl<<endl;
    cout<<"nonoccl errer: ";
    std::cout << 100 * double(nonoccl / double(nonoccl_counter)) << "%"<<endl;
    cout<<endl;

    cout<<"discont_counter = "<<discont_counter<<endl;
    cout<<"discont = "<<discont<<endl;
    cout<<"discont errer: ";
    std::cout << 100 * double(discont / double(discont_counter)) << "%"<<endl;
    cout<<endl;

    cout<<"textl_counter = "<<textl_counter<<endl;
    cout<<"textl = "<<textl<<endl;
    cout<<"textl errer: ";
    std::cout << 100 * double(textl / double(textl_counter)) << "%"<<endl;

    return 0;
}

代码结果

下面就看一下跑的代码结果,下面都是用teddy数据集来跑的结果。

  • semi-global-matching:
rows * cols = 168750
all_counter = 165344
all = 36451
ALL errer: 22.0456%

nonoccl_counter = 147651
nonoccl = 19368
nonoccl errer: 13.1174%

discont_counter = 40517
discont = 14288
discont errer: 35.2642%

textl_counter = 18081
textl = 0
textl errer: 0%

  • SemiGlobal-Matching:
rows * cols = 168750
all_counter = 165344
all = 49526
ALL errer: 29.9533%

nonoccl_counter = 147651
nonoccl = 32484
nonoccl errer: 22.0005%

discont_counter = 40517
discont = 12920
discont errer: 31.8878%

textl_counter = 18081
textl = 0
textl errer: 0%

  • 李博SGM代码
rows * cols = 168750
all_counter = 165344
all = 21203
ALL errer: 12.8236%

nonoccl_counter = 147651
nonoccl = 8440
nonoccl errer: 5.71618%

discont_counter = 40517
discont = 6812
discont errer: 16.8127%

textl_counter = 18081
textl = 0
textl errer: 0%

还可以看一下opencv 的sgbm的测试结果:

  • sgbm:可以看我写的另一篇博客SGBM原理和opencv编程

总结:可以看到,李博的代码结果是最好的。可以参照李博的代码进行改进。

你可能感兴趣的:(传统双目,+,结构光)