1793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*M///////////////////////////////////////////////////////////////////////////////////////
2793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
3793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
5793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  By downloading, copying, installing or using the software you agree to this license.
6793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  If you do not agree to this license, do not download, install,
7793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  copy or use the software.
8793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
9793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
10793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//                           License Agreement
11793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//                For Open Source Computer Vision Library
12793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
13793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Third party copyrights are property of their respective owners.
16793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
17793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Redistribution and use in source and binary forms, with or without modification,
18793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// are permitted provided that the following conditions are met:
19793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
20793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//   * Redistribution's of source code must retain the above copyright notice,
21793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//     this list of conditions and the following disclaimer.
22793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
23793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//   * Redistribution's in binary form must reproduce the above copyright notice,
24793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//     this list of conditions and the following disclaimer in the documentation
25793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//     and/or other materials provided with the distribution.
26793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
27793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//   * The name of the copyright holders may not be used to endorse or promote products
28793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//     derived from this software without specific prior written permission.
29793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
30793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// This software is provided by the copyright holders and contributors "as is" and
31793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// any express or implied warranties, including, but not limited to, the implied
32793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// warranties of merchantability and fitness for a particular purpose are disclaimed.
33793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// In no event shall the Intel Corporation or contributors be liable for any direct,
34793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// indirect, incidental, special, exemplary, or consequential damages
35793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// (including, but not limited to, procurement of substitute goods or services;
36793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// loss of use, data, or profits; or business interruption) however caused
37793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// and on any theory of liability, whether in contract, strict liability,
38793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// or tort (including negligence or otherwise) arising in any way out of
39793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// the use of this software, even if advised of the possibility of such damage.
40793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
41793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//M*/
42793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
43793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "precomp.hpp"
44793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
45793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerusing namespace cv;
46793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerusing namespace cv::cuda;
47793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
48793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#if !defined (HAVE_CUDA) || defined (CUDA_DISABLER)
49793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
50793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid cv::cuda::StereoConstantSpaceBP::estimateRecommendedParams(int, int, int&, int&, int&, int&) { throw_no_cuda(); }
51793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
52793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerPtr<cuda::StereoConstantSpaceBP> cv::cuda::createStereoConstantSpaceBP(int, int, int, int, int) { throw_no_cuda(); return Ptr<cuda::StereoConstantSpaceBP>(); }
53793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
54793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#else /* !defined (HAVE_CUDA) */
55793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
56793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "cuda/stereocsbp.hpp"
57793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
58793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslernamespace
59793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
60793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    class StereoCSBPImpl : public cuda::StereoConstantSpaceBP
61793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
62793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    public:
63793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        StereoCSBPImpl(int ndisp, int iters, int levels, int nr_plane, int msg_type);
64793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
65793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        void compute(InputArray left, InputArray right, OutputArray disparity);
66793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        void compute(InputArray left, InputArray right, OutputArray disparity, Stream& stream);
67793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        void compute(InputArray data, OutputArray disparity, Stream& stream);
68793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
69793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int getMinDisparity() const { return min_disp_th_; }
70793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        void setMinDisparity(int minDisparity) { min_disp_th_ = minDisparity; }
71793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
72793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int getNumDisparities() const { return ndisp_; }
73793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        void setNumDisparities(int numDisparities) { ndisp_ = numDisparities; }
74793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
75793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int getBlockSize() const { return 0; }
76793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        void setBlockSize(int /*blockSize*/) {}
77793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
78793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int getSpeckleWindowSize() const { return 0; }
79793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        void setSpeckleWindowSize(int /*speckleWindowSize*/) {}
80793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
81793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int getSpeckleRange() const { return 0; }
82793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        void setSpeckleRange(int /*speckleRange*/) {}
83793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
84793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int getDisp12MaxDiff() const { return 0; }
85793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        void setDisp12MaxDiff(int /*disp12MaxDiff*/) {}
86793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
87793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int getNumIters() const { return iters_; }
88793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        void setNumIters(int iters) { iters_ = iters; }
89793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
90793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int getNumLevels() const { return levels_; }
91793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        void setNumLevels(int levels) { levels_ = levels; }
92793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
93793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        double getMaxDataTerm() const { return max_data_term_; }
94793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        void setMaxDataTerm(double max_data_term) { max_data_term_ = (float) max_data_term; }
95793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
96793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        double getDataWeight() const { return data_weight_; }
97793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        void setDataWeight(double data_weight) { data_weight_ = (float) data_weight; }
98793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
99793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        double getMaxDiscTerm() const { return max_disc_term_; }
100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        void setMaxDiscTerm(double max_disc_term) { max_disc_term_ = (float) max_disc_term; }
101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        double getDiscSingleJump() const { return disc_single_jump_; }
103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        void setDiscSingleJump(double disc_single_jump) { disc_single_jump_ = (float) disc_single_jump; }
104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int getMsgType() const { return msg_type_; }
106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        void setMsgType(int msg_type) { msg_type_ = msg_type; }
107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int getNrPlane() const { return nr_plane_; }
109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        void setNrPlane(int nr_plane) { nr_plane_ = nr_plane; }
110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        bool getUseLocalInitDataCost() const { return use_local_init_data_cost_; }
112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        void setUseLocalInitDataCost(bool use_local_init_data_cost) { use_local_init_data_cost_ = use_local_init_data_cost; }
113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    private:
115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int min_disp_th_;
116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int ndisp_;
117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int iters_;
118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int levels_;
119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        float max_data_term_;
120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        float data_weight_;
121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        float max_disc_term_;
122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        float disc_single_jump_;
123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int msg_type_;
124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int nr_plane_;
125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        bool use_local_init_data_cost_;
126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GpuMat mbuf_;
128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GpuMat temp_;
129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GpuMat outBuf_;
130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    };
131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    const float DEFAULT_MAX_DATA_TERM = 30.0f;
133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    const float DEFAULT_DATA_WEIGHT = 1.0f;
134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    const float DEFAULT_MAX_DISC_TERM = 160.0f;
135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    const float DEFAULT_DISC_SINGLE_JUMP = 10.0f;
136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    StereoCSBPImpl::StereoCSBPImpl(int ndisp, int iters, int levels, int nr_plane, int msg_type) :
138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        min_disp_th_(0), ndisp_(ndisp), iters_(iters), levels_(levels),
139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        max_data_term_(DEFAULT_MAX_DATA_TERM), data_weight_(DEFAULT_DATA_WEIGHT),
140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        max_disc_term_(DEFAULT_MAX_DISC_TERM), disc_single_jump_(DEFAULT_DISC_SINGLE_JUMP),
141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        msg_type_(msg_type), nr_plane_(nr_plane), use_local_init_data_cost_(true)
142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
143793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void StereoCSBPImpl::compute(InputArray left, InputArray right, OutputArray disparity)
146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        compute(left, right, disparity, Stream::Null());
148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void StereoCSBPImpl::compute(InputArray _left, InputArray _right, OutputArray disp, Stream& _stream)
151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        using namespace cv::cuda::device::stereocsbp;
153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_Assert( msg_type_ == CV_32F || msg_type_ == CV_16S );
155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_Assert( 0 < ndisp_ && 0 < iters_ && 0 < levels_ && 0 < nr_plane_ && levels_ <= 8 );
156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GpuMat left = _left.getGpuMat();
158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GpuMat right = _right.getGpuMat();
159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_Assert( left.type() == CV_8UC1 || left.type() == CV_8UC3 || left.type() == CV_8UC4 );
161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_Assert( left.size() == right.size() && left.type() == right.type() );
162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cudaStream_t stream = StreamAccessor::getStream(_stream);
164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ////////////////////////////////////////////////////////////////////////////////////////////
166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // Init
167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int rows = left.rows;
169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int cols = left.cols;
170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        levels_ = std::min(levels_, int(log((double)ndisp_) / log(2.0)));
172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // compute sizes
174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        AutoBuffer<int> buf(levels_ * 3);
175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int* cols_pyr = buf;
176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int* rows_pyr = cols_pyr + levels_;
177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int* nr_plane_pyr = rows_pyr + levels_;
178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cols_pyr[0]     = cols;
180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        rows_pyr[0]     = rows;
181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        nr_plane_pyr[0] = nr_plane_;
182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for (int i = 1; i < levels_; i++)
184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cols_pyr[i]     = cols_pyr[i-1] / 2;
186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            rows_pyr[i]     = rows_pyr[i-1] / 2;
187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            nr_plane_pyr[i] = nr_plane_pyr[i-1] * 2;
188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GpuMat u[2], d[2], l[2], r[2], disp_selected_pyr[2], data_cost, data_cost_selected;
191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        //allocate buffers
193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int buffers_count = 10; // (up + down + left + right + disp_selected_pyr) * 2
194793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        buffers_count += 2; //  data_cost has twice more rows than other buffers, what's why +2, not +1;
195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        buffers_count += 1; //  data_cost_selected
196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        mbuf_.create(rows * nr_plane_ * buffers_count, cols, msg_type_);
197793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        data_cost          = mbuf_.rowRange(0, rows * nr_plane_ * 2);
199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        data_cost_selected = mbuf_.rowRange(data_cost.rows, data_cost.rows + rows * nr_plane_);
200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for(int k = 0; k < 2; ++k) // in/out
202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            GpuMat sub1 = mbuf_.rowRange(data_cost.rows + data_cost_selected.rows, mbuf_.rows);
204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            GpuMat sub2 = sub1.rowRange((k+0)*sub1.rows/2, (k+1)*sub1.rows/2);
205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            GpuMat *buf_ptrs[] = { &u[k], &d[k], &l[k], &r[k], &disp_selected_pyr[k] };
207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            for(int _r = 0; _r < 5; ++_r)
208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
209793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                *buf_ptrs[_r] = sub2.rowRange(_r * sub2.rows/5, (_r+1) * sub2.rows/5);
210793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CV_DbgAssert( buf_ptrs[_r]->cols == cols && buf_ptrs[_r]->rows == rows * nr_plane_ );
211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        };
213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
214793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        size_t elem_step = mbuf_.step / mbuf_.elemSize();
215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        Size temp_size = data_cost.size();
217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if ((size_t)temp_size.area() < elem_step * rows_pyr[levels_ - 1] * ndisp_)
218793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            temp_size = Size(static_cast<int>(elem_step), rows_pyr[levels_ - 1] * ndisp_);
219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        temp_.create(temp_size, msg_type_);
221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ////////////////////////////////////////////////////////////////////////////
223793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // Compute
224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        l[0].setTo(0, _stream);
226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        d[0].setTo(0, _stream);
227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        r[0].setTo(0, _stream);
228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        u[0].setTo(0, _stream);
229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        l[1].setTo(0, _stream);
231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        d[1].setTo(0, _stream);
232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        r[1].setTo(0, _stream);
233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        u[1].setTo(0, _stream);
234793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
235793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        data_cost.setTo(0, _stream);
236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        data_cost_selected.setTo(0, _stream);
237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int cur_idx = 0;
239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
240793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (msg_type_ == CV_32F)
241793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
242793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            for (int i = levels_ - 1; i >= 0; i--)
243793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
244793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (i == levels_ - 1)
245793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
246793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    init_data_cost(left.ptr<uchar>(), right.ptr<uchar>(), temp_.ptr<uchar>(), left.step, left.rows, left.cols, disp_selected_pyr[cur_idx].ptr<float>(), data_cost_selected.ptr<float>(),
247793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        elem_step, rows_pyr[i], cols_pyr[i], i, nr_plane_pyr[i], ndisp_, left.channels(), data_weight_, max_data_term_, min_disp_th_, use_local_init_data_cost_, stream);
248793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
249793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                else
250793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
251793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    compute_data_cost(left.ptr<uchar>(), right.ptr<uchar>(), left.step, disp_selected_pyr[cur_idx].ptr<float>(), data_cost.ptr<float>(), elem_step,
252793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        left.rows, left.cols, rows_pyr[i], cols_pyr[i], rows_pyr[i+1], i, nr_plane_pyr[i+1], left.channels(), data_weight_, max_data_term_, min_disp_th_, stream);
253793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
254793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    int new_idx = (cur_idx + 1) & 1;
255793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
256793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    init_message(temp_.ptr<uchar>(),
257793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                 u[new_idx].ptr<float>(), d[new_idx].ptr<float>(), l[new_idx].ptr<float>(), r[new_idx].ptr<float>(),
258793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                 u[cur_idx].ptr<float>(), d[cur_idx].ptr<float>(), l[cur_idx].ptr<float>(), r[cur_idx].ptr<float>(),
259793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                 disp_selected_pyr[new_idx].ptr<float>(), disp_selected_pyr[cur_idx].ptr<float>(),
260793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                 data_cost_selected.ptr<float>(), data_cost.ptr<float>(), elem_step, rows_pyr[i],
261793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                 cols_pyr[i], nr_plane_pyr[i], rows_pyr[i+1], cols_pyr[i+1], nr_plane_pyr[i+1], stream);
262793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
263793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cur_idx = new_idx;
264793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
265793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
266793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                calc_all_iterations(temp_.ptr<uchar>(), u[cur_idx].ptr<float>(), d[cur_idx].ptr<float>(), l[cur_idx].ptr<float>(), r[cur_idx].ptr<float>(),
267793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                    data_cost_selected.ptr<float>(), disp_selected_pyr[cur_idx].ptr<float>(), elem_step,
268793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                    rows_pyr[i], cols_pyr[i], nr_plane_pyr[i], iters_, max_disc_term_, disc_single_jump_, stream);
269793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
270793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
271793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        else
272793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
273793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            for (int i = levels_ - 1; i >= 0; i--)
274793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
275793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (i == levels_ - 1)
276793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
277793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    init_data_cost(left.ptr<uchar>(), right.ptr<uchar>(), temp_.ptr<uchar>(), left.step, left.rows, left.cols, disp_selected_pyr[cur_idx].ptr<short>(), data_cost_selected.ptr<short>(),
278793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        elem_step, rows_pyr[i], cols_pyr[i], i, nr_plane_pyr[i], ndisp_, left.channels(), data_weight_, max_data_term_, min_disp_th_, use_local_init_data_cost_, stream);
279793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
280793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                else
281793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
282793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    compute_data_cost(left.ptr<uchar>(), right.ptr<uchar>(), left.step, disp_selected_pyr[cur_idx].ptr<short>(), data_cost.ptr<short>(), elem_step,
283793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        left.rows, left.cols, rows_pyr[i], cols_pyr[i], rows_pyr[i+1], i, nr_plane_pyr[i+1], left.channels(), data_weight_, max_data_term_, min_disp_th_, stream);
284793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
285793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    int new_idx = (cur_idx + 1) & 1;
286793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
287793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    init_message(temp_.ptr<uchar>(),
288793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                 u[new_idx].ptr<short>(), d[new_idx].ptr<short>(), l[new_idx].ptr<short>(), r[new_idx].ptr<short>(),
289793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                 u[cur_idx].ptr<short>(), d[cur_idx].ptr<short>(), l[cur_idx].ptr<short>(), r[cur_idx].ptr<short>(),
290793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                 disp_selected_pyr[new_idx].ptr<short>(), disp_selected_pyr[cur_idx].ptr<short>(),
291793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                 data_cost_selected.ptr<short>(), data_cost.ptr<short>(), elem_step, rows_pyr[i],
292793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                 cols_pyr[i], nr_plane_pyr[i], rows_pyr[i+1], cols_pyr[i+1], nr_plane_pyr[i+1], stream);
293793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
294793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cur_idx = new_idx;
295793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
296793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
297793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                calc_all_iterations(temp_.ptr<uchar>(), u[cur_idx].ptr<short>(), d[cur_idx].ptr<short>(), l[cur_idx].ptr<short>(), r[cur_idx].ptr<short>(),
298793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                    data_cost_selected.ptr<short>(), disp_selected_pyr[cur_idx].ptr<short>(), elem_step,
299793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                    rows_pyr[i], cols_pyr[i], nr_plane_pyr[i], iters_, max_disc_term_, disc_single_jump_, stream);
300793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
301793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
302793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
303793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        const int dtype = disp.fixedType() ? disp.type() : CV_16SC1;
304793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
305793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        disp.create(rows, cols, dtype);
306793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GpuMat out = disp.getGpuMat();
307793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
308793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (dtype != CV_16SC1)
309793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
310793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            outBuf_.create(rows, cols, CV_16SC1);
311793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            out = outBuf_;
312793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
313793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
314793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        out.setTo(0, _stream);
315793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
316793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (msg_type_ == CV_32F)
317793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
318793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            compute_disp(u[cur_idx].ptr<float>(), d[cur_idx].ptr<float>(), l[cur_idx].ptr<float>(), r[cur_idx].ptr<float>(),
319793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                         data_cost_selected.ptr<float>(), disp_selected_pyr[cur_idx].ptr<float>(), elem_step, out, nr_plane_pyr[0], stream);
320793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
321793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        else
322793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
323793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            compute_disp(u[cur_idx].ptr<short>(), d[cur_idx].ptr<short>(), l[cur_idx].ptr<short>(), r[cur_idx].ptr<short>(),
324793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                         data_cost_selected.ptr<short>(), disp_selected_pyr[cur_idx].ptr<short>(), elem_step, out, nr_plane_pyr[0], stream);
325793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
326793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
327793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (dtype != CV_16SC1)
328793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            out.convertTo(disp, dtype, _stream);
329793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
330793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
331793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void StereoCSBPImpl::compute(InputArray /*data*/, OutputArray /*disparity*/, Stream& /*stream*/)
332793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
333793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_Error(Error::StsNotImplemented, "Not implemented");
334793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
335793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
336793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
337793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerPtr<cuda::StereoConstantSpaceBP> cv::cuda::createStereoConstantSpaceBP(int ndisp, int iters, int levels, int nr_plane, int msg_type)
338793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
339793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return makePtr<StereoCSBPImpl>(ndisp, iters, levels, nr_plane, msg_type);
340793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
341793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
342793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid cv::cuda::StereoConstantSpaceBP::estimateRecommendedParams(int width, int height, int& ndisp, int& iters, int& levels, int& nr_plane)
343793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
344793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    ndisp = (int) ((float) width / 3.14f);
345793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if ((ndisp & 1) != 0)
346793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ndisp++;
347793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
348793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int mm = std::max(width, height);
349793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    iters = mm / 100 + ((mm > 1200)? - 4 : 4);
350793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
351793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    levels = (int)::log(static_cast<double>(mm)) * 2 / 3;
352793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (levels == 0) levels++;
353793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
354793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    nr_plane = (int) ((float) ndisp / std::pow(2.0, levels + 1));
355793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
356793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
357793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif /* !defined (HAVE_CUDA) */
358