Introduction 
Stereo matching algorithms, especially highly-optimized ones that are intended for real-time processing on CPU, tend to make quite a few errors on challenging sequences. These errors are usually concentrated in uniform texture-less areas, half-occlusions and regions near depth discontinuities. One way of dealing with stereo-matching errors is to use various techniques of detecting potentially inaccurate disparity values and invalidate them, therefore making the disparity map semi-sparse. Several such techniques are already implemented in the StereoBM and StereoSGBM algorithms. Another way would be to use some kind of filtering procedure to align the disparity map edges with those of the source image and to propagate the disparity values from high- to low-confidence regions like half-occlusions. Recent advances in edge-aware filtering have enabled performing such post-filtering under the constraints of real-time processing on CPU.
In this tutorial you will learn how to use the disparity map post-filtering to improve the results of StereoBM and StereoSGBM algorithms.
Source Stereoscopic Image 
 
Left view
 
 
Right view
 
 Source Code 
We will be using snippets from the example application, that can be downloaded here.
Explanation 
The provided example has several options that yield different trade-offs between the speed and the quality of the resulting disparity map. Both the speed and the quality are measured if the user has provided the ground-truth disparity map. In this tutorial we will take a detailed look at the default pipeline, that was designed to provide the best possible quality under the constraints of real-time processing on CPU.
- Load left and right views     if ( left.empty() )     {         cout<<"Cannot read image file: "<<left_im;         return -1;     }     if ( right.empty() )     {         cout<<"Cannot read image file: "<<right_im;         return -1;     } 
- Prepare the views for matching             max_disp/=2;             if(max_disp%16!=0)                 max_disp += 16-(max_disp%16); 
- Perform matching and create the filter instance             Ptr<StereoBM> left_matcher = StereoBM::create(max_disp,wsize);             left_matcher-> compute(left_for_matcher, right_for_matcher,left_disp);             right_matcher->compute(right_for_matcher,left_for_matcher, right_disp); 
- Perform filtering         wls_filter->setLambda(lambda);         wls_filter->setSigmaColor(sigma);         wls_filter->filter(left_disp,left,filtered_disp,right_disp); 
- Visualize the disparity maps         Mat raw_disp_vis;         imshow( "raw disparity", raw_disp_vis); 
         Mat filtered_disp_vis;         imshow( "filtered disparity", filtered_disp_vis); 
         if(!solved_disp.empty())         {             Mat solved_disp_vis;             imshow( "solved disparity", solved_disp_vis); 
             Mat solved_filtered_disp_vis;             imshow( "solved wls disparity", solved_filtered_disp_vis); 
         }         while(1)         {             if( key == 27 || key == 'q' || key == 'Q')                  break;         } 
Results 
 
Result of the StereoBM
 
 
Result of the demonstrated pipeline (StereoBM on downscaled views with post-filtering)