• DisparityCostVolumeEstimator.cpp


    #include "DisparityCostVolumeEstimator.hpp"
    
    #include "DisparityCostVolume.hpp"
    
    #include "stereo_matching/cost_functions.hpp"
    
    #include "helpers/get_option_value.hpp"
    #include "helpers/fill_multi_array.hpp"
    
    #include <boost/gil/image_view_factory.hpp>
    
    namespace doppia
    {
    
    using namespace boost;
    using namespace boost::gil;
    using namespace std;
    
    typedef DisparityCostVolume::range_t range_t;
    typedef DisparityCostVolume::const_data_2d_view_t const_data_2d_view_t;
    typedef DisparityCostVolume::const_data_1d_view_t const_data_1d_view_t;
    typedef DisparityCostVolume::const_data_2d_subarray_t const_data_2d_subarray_t;
    typedef DisparityCostVolume::const_data_1d_subarray_t const_data_1d_subarray_t;
    typedef DisparityCostVolume::data_3d_view_t data_3d_view_t;
    
    
    program_options::options_description  DisparityCostVolumeEstimator::get_args_options()
    {
        program_options::options_description desc("DisparityCostVolumeEstimator options");
    
        const bool simple_block_matcher_options_are_included = true;
    
        if(not simple_block_matcher_options_are_included)
        {
            desc.add_options()
    
                    ("pixels_matching",
                     program_options::value<string>()->default_value("sad"),
                     "pixels matching method: sad, ssd, census or gradient")
    
                    ("threshold",
                     program_options::value<float>()->default_value(0.5),
                     "minimum percent of pixels required to declare a match value between [0,1]")
    
                    ;
        }
    
        return desc;
    }
    
    DisparityCostVolumeEstimator::DisparityCostVolumeEstimator()
        : AbstractDisparityCostVolumeEstimator()
    {
        // this constructor should only be used for unit testing
        return;
    }
    
    DisparityCostVolumeEstimator::DisparityCostVolumeEstimator(const program_options::variables_map &options)
        : AbstractDisparityCostVolumeEstimator(options)
    {
    
        threshold_percent = get_option_value<float>(options,"threshold");
    
        assert(threshold_percent > 0.0f);
        assert(threshold_percent <= 1.0f);
    
        return;
    }
    
    DisparityCostVolumeEstimator::~DisparityCostVolumeEstimator()
    {
        // nothing to do here
        return;
    }
    
    
    void  DisparityCostVolumeEstimator::compute(gil::gray8c_view_t &left,
                                                gil::gray8c_view_t &right,
                                                DisparityCostVolume &cost_volume)
    {
        compute_impl(left, right, cost_volume);
        return;
    }
    
    void  DisparityCostVolumeEstimator::compute(gil::rgb8c_view_t  &left,
                                                gil::rgb8c_view_t &right,
                                                DisparityCostVolume &cost_volume)
    {
        compute_impl(left, right, cost_volume);
        return;
    }
    
    
    template <typename ImgView>
    void DisparityCostVolumeEstimator::compute_impl( ImgView &left, ImgView &right, DisparityCostVolume &cost_volume)
    {
    
        if (pixels_matching_method == "sad")
        {
            if(first_computation)
            {
                printf("DisparityCostVolumeEstimator::compute_impl will use sad matching over %zi disparities
    
    ",
                       max_disparity);
            }
            SadCostFunctionT<uint8_t> pixels_distance;
            compute_costs_impl(left, right, pixels_distance, cost_volume);
        }
        else if (pixels_matching_method == "ssd")
        {
            if(first_computation)
            {
                printf("DisparityCostVolumeEstimator::compute_impl will use ssd matching over %zi disparities
    
    ",
                       max_disparity);
            }
            SsdCostFunction pixels_distance;
            compute_costs_impl(left, right, pixels_distance, cost_volume);
        }
        else
        {
            printf("DisparityCostVolumeEstimator::compute_impl received an unknow pixels_matching_method value == %s
    ",
                   pixels_matching_method.c_str());
    
            throw std::invalid_argument("DisparityCostVolumeEstimator::compute_impl received an unknow pixels_matching_method");
        }
    
        first_computation = false;
    
        return;
    }
    
    
    
    
    template <typename ImgView, typename PixelsCostType>
    inline void compute_costs_for_disparity(const ImgView &left, const ImgView &right,
                                            PixelsCostType &pixels_distance,
                                            const int disparity,
                                            DisparityCostVolume::data_2d_view_t &disparity_cost_view)
    {
        typedef typename ImgView::value_type pixel_t;
        typedef  DisparityCostVolume::data_1d_subarray_t data_1d_subarray_t;
    
        // a pixel (x,y) on the left image should be matched on the right image on the range ([0,x],y)
        //const int first_right_x = first_left_x - disparity;
    
        for(int y=0; y < left.height(); y+=1)
        {
            typename ImgView::x_iterator left_row_it = left.x_at(disparity, y);
            typename ImgView::x_iterator right_row_it = right.row_begin(y);
            data_1d_subarray_t cost_row_subarray = disparity_cost_view[y];
            data_1d_subarray_t::iterator cost_it = cost_row_subarray.begin() + disparity;
            for(int left_x=disparity; left_x < left.width(); left_x+=1, ++left_row_it, ++right_row_it, ++cost_it)
            {
                const DisparityCostVolume::cost_t pixel_cost = pixels_distance(*left_row_it, *right_row_it);
                *cost_it = pixel_cost;
            } // end of 'for each row'
        } // end of 'for each column'
    
        return;
    }
    
    
    
    template <typename ImgView, typename PixelsCostType>
    void DisparityCostVolumeEstimator::compute_costs_impl(const ImgView &left, const ImgView &right,
                                                          PixelsCostType &pixels_distance,
                                                          DisparityCostVolume &cost_volume)
    {
    
        typedef typename ImgView::value_type pixel_t;
        maximum_cost_per_pixel = pixels_distance.template get_maximum_cost_per_pixel<pixel_t>();
    
        // lazy initialization
        this->resize_cost_volume(left.dimensions(), cost_volume);
    
        const bool crop_borders = false;
    
        if(crop_borders)
        {
            // FIXME hardcoded values
            const int top_bottom_margin = 25; // 20 // 10 // pixels
            const int left_right_margin = 40; //left.width()*0.1;  // *0.05 // pixels
    
            const int
                    sub_width = left.width() - 2*left_right_margin,
                    sub_height = left.height() - 2*top_bottom_margin;
            const ImgView
                    left_subview = boost::gil::subimage_view(left,
                                                             left_right_margin, top_bottom_margin,
                                                             sub_width, sub_height),
                    right_subview = boost::gil::subimage_view(right,
                                                              left_right_margin,top_bottom_margin,
                                                              sub_width, sub_height);
    
    
            const int y_min = top_bottom_margin, y_max = left.height() - top_bottom_margin;
            const int x_min = left_right_margin, x_max = left.width() - left_right_margin;
            data_3d_view_t data = cost_volume.get_costs_views();
            data_3d_view_t
                    data_subview = data[ boost::indices[range_t(y_min, y_max)][range_t(x_min, x_max)][range_t()] ];
    
            // fill the original volumn with zero
            fill(cost_volume.get_costs_views(), 0);
    
    #pragma omp parallel for
            for(size_t disparity=0; disparity < max_disparity; disparity +=1)
            {
                DisparityCostVolume::data_2d_view_t disparity_slice = data_subview[ boost::indices[range_t()][range_t()][disparity] ];
                compute_costs_for_disparity(left_subview, right_subview, pixels_distance, disparity, disparity_slice);
            }
    
        }
        else
        {
    
            // for each pixel and each disparity value
    #pragma omp parallel for
            for(size_t disparity=0; disparity < max_disparity; disparity +=1)
            {
                data_3d_view_t data = cost_volume.get_costs_views();
                DisparityCostVolume::data_2d_view_t disparity_slice = data[ boost::indices[range_t()][range_t()][disparity] ];
                compute_costs_for_disparity(left, right, pixels_distance, disparity, disparity_slice);
            }
    
        } // end of "if else crop_borders"
    
        return;
    }
    
    
    
    } // end of namespace doppia

    ImgView这个模版类没有找到

    SsdCostFunction、SadCostFunctionT来自cost_functions.hpp,实际上就是具体值怎么计算

  • 相关阅读:
    DeepEarth开发文章汇总
    让人期待的Visual Studio 2010
    Silverlight & Blend动画设计系列文章
    杜拉拉“植入式营销”魔法(为写植入式广告fxgj介绍)
    C++ String Split
    一个类似Java String[] split(String regex)的VC++函数
    MSChart控件的属性与属性对话框
    植入式广告介绍 撰写 素材
    植入式营销 为何不能植入顾客脑海
    PQA2000 地震应急救生器
  • 原文地址:https://www.cnblogs.com/ymjyqsx/p/9288872.html
Copyright © 2020-2023  润新知