Skip to content

Commit 7c421ba

Browse files
committed
Adding confidence support and optimizing disparity filtering
DisparityWLSFilter demonstrated the best results, so I removed all the other filters. Quality was significantly improved by adding confidence support to the filter (left-right consistency + penalty for areas near depth discontinuities). Filter was optimized using parallel_for_ and HAL intrinsics. Demo application was rewritten for better compliance with OpenCV standards. Added accuracy and performance tests. Documentation was added, as well as references to the original papers.
1 parent a70af9f commit 7c421ba

19 files changed

+2101
-602
lines changed

modules/ximgproc/doc/ximgproc.bib

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,25 @@ @inproceedings{Lim2013
5555
year={2013},
5656
organization={IEEE}
5757
}
58+
59+
@article{Min2014,
60+
title={Fast global image smoothing based on weighted least squares},
61+
author={Min, Dongbo and Choi, Sunghwan and Lu, Jiangbo and Ham, Bumsub and Sohn, Kwanghoon and Do, Minh N},
62+
journal={Image Processing, IEEE Transactions on},
63+
volume={23},
64+
number={12},
65+
pages={5638--5653},
66+
year={2014},
67+
publisher={IEEE}
68+
}
69+
70+
@inproceedings{Farbman2008,
71+
title={Edge-preserving decompositions for multi-scale tone and detail manipulation},
72+
author={Farbman, Zeev and Fattal, Raanan and Lischinski, Dani and Szeliski, Richard},
73+
booktitle={ACM Transactions on Graphics (TOG)},
74+
volume={27},
75+
number={3},
76+
pages={67},
77+
year={2008},
78+
organization={ACM}
79+
}

modules/ximgproc/include/opencv2/ximgproc.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#define __OPENCV_XIMGPROC_HPP__
3939

4040
#include "ximgproc/edge_filter.hpp"
41+
#include "ximgproc/disparity_filter.hpp"
4142
#include "ximgproc/structured_edge_detection.hpp"
4243
#include "ximgproc/seeds.hpp"
4344

modules/ximgproc/include/opencv2/ximgproc/disparity_filter.hpp

Lines changed: 122 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -43,49 +43,147 @@
4343
namespace cv {
4444
namespace ximgproc {
4545

46+
//! @addtogroup ximgproc_filters
47+
//! @{
48+
49+
/** @brief Main interface for all disparity map filters.
50+
*/
4651
class CV_EXPORTS_W DisparityFilter : public Algorithm
4752
{
4853
public:
49-
CV_WRAP virtual void filter(InputArray disparity_map, InputArray left_view, OutputArray filtered_disparity_map,Rect ROI) = 0;
50-
};
5154

52-
/////////////////////////////////////////////////////////////////////////////////////////////////
55+
/** @brief Apply filtering to the disparity map.
5356
54-
class CV_EXPORTS_W DisparityDTFilter : public DisparityFilter
55-
{
56-
public:
57-
CV_WRAP virtual double getSigmaSpatial() = 0;
58-
CV_WRAP virtual void setSigmaSpatial(double _sigmaSpatial) = 0;
59-
CV_WRAP virtual double getSigmaColor() = 0;
60-
CV_WRAP virtual void setSigmaColor(double _sigmaColor) = 0;
61-
};
57+
@param disparity_map_left disparity map of the left view, 1 channel, CV_16S type. Implicitly assumes that disparity
58+
values are scaled by 16 (one-pixel disparity corresponds to the value of 16 in the disparity map). Disparity map
59+
can have any resolution, it will be automatically resized to fit left_view resolution.
6260
63-
CV_EXPORTS_W
64-
Ptr<DisparityDTFilter> createDisparityDTFilter();
61+
@param left_view left view of the original stereo-pair to guide the filtering process, 8-bit single-channel
62+
or three-channel image.
6563
66-
class CV_EXPORTS_W DisparityGuidedFilter : public DisparityFilter
67-
{
68-
public:
69-
CV_WRAP virtual double getEps() = 0;
70-
CV_WRAP virtual void setEps(double _eps) = 0;
71-
CV_WRAP virtual int getRadius() = 0;
72-
CV_WRAP virtual void setRadius(int _radius) = 0;
73-
};
64+
@param filtered_disparity_map output disparity map.
7465
75-
CV_EXPORTS_W
76-
Ptr<DisparityGuidedFilter> createDisparityGuidedFilter();
66+
@param ROI region of the disparity map to filter.
7767
68+
@param disparity_map_right optional argument, some implementations might also use the disparity map
69+
of the right view to compute confidence maps, for instance.
70+
71+
@param right_view optional argument, some implementations might also use the right view of the original
72+
stereo-pair.
73+
*/
74+
CV_WRAP virtual void filter(InputArray disparity_map_left, InputArray left_view, OutputArray filtered_disparity_map, Rect ROI, InputArray disparity_map_right = Mat(), InputArray right_view = Mat()) = 0;
75+
};
76+
77+
/** @brief Disparity map filter based on Weighted Least Squares filter (in form of Fast Global Smoother that
78+
is a lot faster than traditional Weighted Least Squares filter implementations) and optional use of
79+
left-right-consistency-based confidence to refine the results in half-occlusions and uniform areas.
80+
*/
7881
class CV_EXPORTS_W DisparityWLSFilter : public DisparityFilter
7982
{
83+
public:
84+
/** filter parameters */
85+
86+
/** @brief Lambda is a parameter defining the amount of regularization during filtering. Larger values force
87+
filtered disparity map edges to adhere more to source image edges. Typical value is 8000.
88+
*/
8089
CV_WRAP virtual double getLambda() = 0;
90+
/** @see getLambda */
8191
CV_WRAP virtual void setLambda(double _lambda) = 0;
92+
/** @brief SigmaColor is a parameter defining how sensitive the filtering process is to source image edges.
93+
Large values can lead to disparity leakage through low-contrast edges. Small values can make the filter too
94+
sensitive to noise and textures in the source image. Typical values range from 0.8 to 2.0.
95+
*/
8296
CV_WRAP virtual double getSigmaColor() = 0;
97+
/** @see getSigmaColor */
8398
CV_WRAP virtual void setSigmaColor(double _sigma_color) = 0;
99+
100+
/** confidence-related parameters */
101+
102+
/** @brief LRCthresh is a threshold of disparity difference used in left-right-consistency check during
103+
confidence map computation. The default value of 24 (1.5 pixels) is virtually always good enough.
104+
*/
105+
CV_WRAP virtual int getLRCthresh() = 0;
106+
/** @see getLRCthresh */
107+
CV_WRAP virtual void setLRCthresh(int _LRC_thresh) = 0;
108+
/** @brief DepthDiscontinuityRadius is a parameter used in confidence computation. It defines the size of
109+
low-confidence regions around depth discontinuities. For typical window sizes used in stereo matching the
110+
optimal value is around 5.
111+
*/
112+
CV_WRAP virtual int getDepthDiscontinuityRadius() = 0;
113+
/** @see getDepthDiscontinuityRadius */
114+
CV_WRAP virtual void setDepthDiscontinuityRadius(int _disc_radius) = 0;
115+
/** @brief Get the confidence map that was used in the last filter call. It is a CV_32F one-channel image
116+
with values ranging from 0.0 (totally untrusted regions of the raw disparity map) to 255.0 (regions containing
117+
correct disparity values with a high degree of confidence).
118+
*/
119+
CV_WRAP virtual Mat getConfidenceMap() = 0;
120+
84121
};
85122

123+
/** @brief Factory method, create instance of DisparityWLSFilter and execute the initialization routines.
124+
125+
@param use_confidence filtering with confidence requires two disparity maps (for the left and right views) and is
126+
approximately two times slower. However, quality is typically significantly better.
127+
*/
86128
CV_EXPORTS_W
87-
Ptr<DisparityWLSFilter> createDisparityWLSFilter();
129+
Ptr<DisparityWLSFilter> createDisparityWLSFilter(bool use_confidence);
130+
131+
//////////////////////////////////////////////////////////////////////////
132+
//////////////////////////////////////////////////////////////////////////
133+
134+
/** @brief Function for reading ground truth disparity maps. Supports basic Middlebury
135+
and MPI-Sintel formats. Note that the resulting disparity map is scaled by 16.
136+
137+
@param src_path path to the image, containing ground-truth disparity map
138+
139+
@param dst output disparity map, CV_16S depth
140+
141+
@result returns zero if successfully read the ground truth
142+
*/
143+
CV_EXPORTS
144+
int readGT(String src_path,OutputArray dst);
145+
146+
/** @brief Function for computing mean square error for disparity maps
147+
148+
@param GT ground truth disparity map
149+
150+
@param src disparity map to evaluate
151+
152+
@param ROI region of interest
153+
154+
@result returns mean square error between GT and src
155+
*/
156+
CV_EXPORTS
157+
double computeMSE(InputArray GT, InputArray src, Rect ROI);
158+
159+
/** @brief Function for computing the percent of "bad" pixels in the disparity map
160+
(pixels where error is higher than a specified threshold)
161+
162+
@param GT ground truth disparity map
163+
164+
@param src disparity map to evaluate
165+
166+
@param ROI region of interest
167+
168+
@param thresh threshold used to determine "bad" pixels
169+
170+
@result returns mean square error between GT and src
171+
*/
172+
CV_EXPORTS
173+
double computeBadPixelPercent(InputArray GT, InputArray src, Rect ROI, int thresh=24/*1.5 pixels*/);
174+
175+
/** @brief Function for creating a disparity map visualization (clamped CV_8U image)
176+
177+
@param src input disparity map (CV_16S depth)
178+
179+
@param dst output visualization
180+
181+
@param scale disparity map will be multiplied by this value for visualization
182+
*/
183+
CV_EXPORTS
184+
void getDisparityVis(InputArray src,OutputArray dst,double scale=1.0);
88185

186+
//! @}
89187
}
90188
}
91189
#endif

modules/ximgproc/include/opencv2/ximgproc/edge_filter.hpp

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -316,19 +316,69 @@ proportional to sigmaSpace .
316316
CV_EXPORTS_W
317317
void jointBilateralFilter(InputArray joint, InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType = BORDER_DEFAULT);
318318

319-
//! @}
319+
//////////////////////////////////////////////////////////////////////////
320+
//////////////////////////////////////////////////////////////////////////
321+
320322

321-
class CV_EXPORTS_W WeightedLeastSquaresFilter : public Algorithm
323+
/** @brief Interface for implementations of Fast Global Smoother filter.
324+
325+
For more details about this filter see @cite Min2014 and @cite Farbman2008 .
326+
*/
327+
class CV_EXPORTS_W FastGlobalSmootherFilter : public Algorithm
322328
{
323329
public:
330+
/** @brief Apply smoothing operation to the source image.
331+
332+
@param src source image for filtering with unsigned 8-bit or signed 16-bit or floating-point 32-bit depth and up to 4 channels.
333+
334+
@param dst destination image.
335+
*/
324336
CV_WRAP virtual void filter(InputArray src, OutputArray dst) = 0;
325-
virtual ~WeightedLeastSquaresFilter();
326337
};
327338

328-
CV_EXPORTS_W Ptr<WeightedLeastSquaresFilter> createWeightedLeastSquaresFilter(InputArray guide, double lambda, double sigma_color, int num_iter=3);
339+
/** @brief Factory method, create instance of FastGlobalSmootherFilter and execute the initialization routines.
340+
341+
@param guide image serving as guide for filtering. It should have 8-bit depth and either 1 or 3 channels.
342+
343+
@param lambda parameter defining the amount of regularization
344+
345+
@param sigma_color parameter, that is similar to color space sigma in bilateralFilter.
346+
347+
@param lambda_attenuation internal parameter, defining how much lambda decreases after each iteration. Normally,
348+
it should be 0.25. Setting it to 1.0 may lead to streaking artifacts.
329349
330-
CV_EXPORTS_W void weightedLeastSquaresFilter(InputArray guide, InputArray src, OutputArray dst, double lambda, double sigma_color, int num_iter=3);
350+
@param num_iter number of iterations used for filtering, 3 is usually enough.
331351
352+
For more details about Fast Global Smoother parameters, see the original paper @cite Min2014. However, please note that
353+
there are several differences. Lambda attenuation described in the paper is implemented a bit differently so do not
354+
expect the results to be identical to those from the paper; sigma_color values from the paper should be multiplied by 255.0 to
355+
achieve the same effect. Also, in case of image filtering where source and guide image are the same, authors
356+
propose to dynamically update the guide image after each iteration. To maximize the performance this feature
357+
was not implemented here.
358+
*/
359+
CV_EXPORTS_W Ptr<FastGlobalSmootherFilter> createFastGlobalSmootherFilter(InputArray guide, double lambda, double sigma_color, double lambda_attenuation=0.25, int num_iter=3);
360+
361+
/** @brief Simple one-line Fast Global Smoother filter call. If you have multiple images to filter with the same
362+
guide then use FastGlobalSmootherFilter interface to avoid extra computations.
363+
364+
@param guide image serving as guide for filtering. It should have 8-bit depth and either 1 or 3 channels.
365+
366+
@param src source image for filtering with unsigned 8-bit or signed 16-bit or floating-point 32-bit depth and up to 4 channels.
367+
368+
@param dst destination image.
369+
370+
@param lambda parameter defining the amount of regularization
371+
372+
@param sigma_color parameter, that is similar to color space sigma in bilateralFilter.
373+
374+
@param lambda_attenuation internal parameter, defining how much lambda decreases after each iteration. Normally,
375+
it should be 0.25. Setting it to 1.0 may lead to streaking artifacts.
376+
377+
@param num_iter number of iterations used for filtering, 3 is usually enough.
378+
*/
379+
CV_EXPORTS_W void fastGlobalSmootherFilter(InputArray guide, InputArray src, OutputArray dst, double lambda, double sigma_color, double lambda_attenuation=0.25, int num_iter=3);
380+
381+
//! @}
332382
}
333383
}
334384
#endif

0 commit comments

Comments
 (0)