refactored DisparityBilateralFilter
This commit is contained in:
parent
be9bb8f18b
commit
3a02e599e0
@ -134,44 +134,48 @@ public:
|
||||
CV_EXPORTS Ptr<gpu::StereoConstantSpaceBP>
|
||||
createStereoConstantSpaceBP(int ndisp = 128, int iters = 8, int levels = 4, int nr_plane = 4, int msg_type = CV_32F);
|
||||
|
||||
/////////////////////////////////////////
|
||||
// DisparityBilateralFilter
|
||||
|
||||
|
||||
|
||||
// Disparity map refinement using joint bilateral filtering given a single color image.
|
||||
// Qingxiong Yang, Liang Wang, Narendra Ahuja
|
||||
// http://vision.ai.uiuc.edu/~qyang6/
|
||||
class CV_EXPORTS DisparityBilateralFilter
|
||||
//! Disparity map refinement using joint bilateral filtering given a single color image.
|
||||
//! Qingxiong Yang, Liang Wang, Narendra Ahuja
|
||||
//! http://vision.ai.uiuc.edu/~qyang6/
|
||||
class CV_EXPORTS DisparityBilateralFilter : public cv::Algorithm
|
||||
{
|
||||
public:
|
||||
enum { DEFAULT_NDISP = 64 };
|
||||
enum { DEFAULT_RADIUS = 3 };
|
||||
enum { DEFAULT_ITERS = 1 };
|
||||
|
||||
//! the default constructor
|
||||
explicit DisparityBilateralFilter(int ndisp = DEFAULT_NDISP, int radius = DEFAULT_RADIUS, int iters = DEFAULT_ITERS);
|
||||
|
||||
//! the full constructor taking the number of disparities, filter radius,
|
||||
//! number of iterations, truncation of data continuity, truncation of disparity continuity
|
||||
//! and filter range sigma
|
||||
DisparityBilateralFilter(int ndisp, int radius, int iters, float edge_threshold, float max_disc_threshold, float sigma_range);
|
||||
|
||||
//! the disparity map refinement operator. Refine disparity map using joint bilateral filtering given a single color image.
|
||||
//! disparity must have CV_8U or CV_16S type, image must have CV_8UC1 or CV_8UC3 type.
|
||||
void operator()(const GpuMat& disparity, const GpuMat& image, GpuMat& dst, Stream& stream = Stream::Null());
|
||||
virtual void apply(InputArray disparity, InputArray image, OutputArray dst, Stream& stream = Stream::Null()) = 0;
|
||||
|
||||
private:
|
||||
int ndisp;
|
||||
int radius;
|
||||
int iters;
|
||||
virtual int getNumDisparities() const = 0;
|
||||
virtual void setNumDisparities(int numDisparities) = 0;
|
||||
|
||||
float edge_threshold;
|
||||
float max_disc_threshold;
|
||||
float sigma_range;
|
||||
virtual int getRadius() const = 0;
|
||||
virtual void setRadius(int radius) = 0;
|
||||
|
||||
GpuMat table_color;
|
||||
GpuMat table_space;
|
||||
virtual int getNumIters() const = 0;
|
||||
virtual void setNumIters(int iters) = 0;
|
||||
|
||||
//! truncation of data continuity
|
||||
virtual double getEdgeThreshold() const = 0;
|
||||
virtual void setEdgeThreshold(double edge_threshold) = 0;
|
||||
|
||||
//! truncation of disparity continuity
|
||||
virtual double getMaxDiscThreshold() const = 0;
|
||||
virtual void setMaxDiscThreshold(double max_disc_threshold) = 0;
|
||||
|
||||
//! filter range sigma
|
||||
virtual double getSigmaRange() const = 0;
|
||||
virtual void setSigmaRange(double sigma_range) = 0;
|
||||
};
|
||||
|
||||
CV_EXPORTS Ptr<gpu::DisparityBilateralFilter>
|
||||
createDisparityBilateralFilter(int ndisp = 64, int radius = 3, int iters = 1);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//! Reprojects disparity image to 3D space.
|
||||
//! Supports CV_8U and CV_16S types of input disparity.
|
||||
//! The output is a 3- or 4-channel floating-point matrix.
|
||||
|
@ -173,13 +173,13 @@ PERF_TEST_P(ImagePair, DisparityBilateralFilter,
|
||||
|
||||
if (PERF_RUN_GPU())
|
||||
{
|
||||
cv::gpu::DisparityBilateralFilter d_filter(ndisp);
|
||||
cv::Ptr<cv::gpu::DisparityBilateralFilter> d_filter = cv::gpu::createDisparityBilateralFilter(ndisp);
|
||||
|
||||
const cv::gpu::GpuMat d_img(img);
|
||||
const cv::gpu::GpuMat d_disp(disp);
|
||||
cv::gpu::GpuMat dst;
|
||||
|
||||
TEST_CYCLE() d_filter(d_disp, d_img, dst);
|
||||
TEST_CYCLE() d_filter->apply(d_disp, d_img, dst);
|
||||
|
||||
GPU_SANITY_CHECK(dst);
|
||||
}
|
||||
|
@ -47,10 +47,7 @@ using namespace cv::gpu;
|
||||
|
||||
#if !defined (HAVE_CUDA) || defined (CUDA_DISABLER)
|
||||
|
||||
cv::gpu::DisparityBilateralFilter::DisparityBilateralFilter(int, int, int) { throw_no_cuda(); }
|
||||
cv::gpu::DisparityBilateralFilter::DisparityBilateralFilter(int, int, int, float, float, float) { throw_no_cuda(); }
|
||||
|
||||
void cv::gpu::DisparityBilateralFilter::operator()(const GpuMat&, const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); }
|
||||
Ptr<gpu::DisparityBilateralFilter> cv::gpu::createDisparityBilateralFilter(int, int, int) { throw_no_cuda(); return Ptr<gpu::DisparityBilateralFilter>(); }
|
||||
|
||||
#else /* !defined (HAVE_CUDA) */
|
||||
|
||||
@ -65,15 +62,46 @@ namespace cv { namespace gpu { namespace cudev
|
||||
}
|
||||
}}}
|
||||
|
||||
using namespace ::cv::gpu::cudev::disp_bilateral_filter;
|
||||
|
||||
namespace
|
||||
{
|
||||
const float DEFAULT_EDGE_THRESHOLD = 0.1f;
|
||||
const float DEFAULT_MAX_DISC_THRESHOLD = 0.2f;
|
||||
const float DEFAULT_SIGMA_RANGE = 10.0f;
|
||||
class DispBilateralFilterImpl : public gpu::DisparityBilateralFilter
|
||||
{
|
||||
public:
|
||||
DispBilateralFilterImpl(int ndisp, int radius, int iters);
|
||||
|
||||
inline void calc_color_weighted_table(GpuMat& table_color, float sigma_range, int len)
|
||||
void apply(InputArray disparity, InputArray image, OutputArray dst, Stream& stream);
|
||||
|
||||
int getNumDisparities() const { return ndisp_; }
|
||||
void setNumDisparities(int numDisparities) { ndisp_ = numDisparities; }
|
||||
|
||||
int getRadius() const { return radius_; }
|
||||
void setRadius(int radius);
|
||||
|
||||
int getNumIters() const { return iters_; }
|
||||
void setNumIters(int iters) { iters_ = iters; }
|
||||
|
||||
double getEdgeThreshold() const { return edge_threshold_; }
|
||||
void setEdgeThreshold(double edge_threshold) { edge_threshold_ = (float) edge_threshold; }
|
||||
|
||||
double getMaxDiscThreshold() const { return max_disc_threshold_; }
|
||||
void setMaxDiscThreshold(double max_disc_threshold) { max_disc_threshold_ = (float) max_disc_threshold; }
|
||||
|
||||
double getSigmaRange() const { return sigma_range_; }
|
||||
void setSigmaRange(double sigma_range);
|
||||
|
||||
private:
|
||||
int ndisp_;
|
||||
int radius_;
|
||||
int iters_;
|
||||
float edge_threshold_;
|
||||
float max_disc_threshold_;
|
||||
float sigma_range_;
|
||||
|
||||
GpuMat table_color_;
|
||||
GpuMat table_space_;
|
||||
};
|
||||
|
||||
void calc_color_weighted_table(GpuMat& table_color, float sigma_range, int len)
|
||||
{
|
||||
Mat cpu_table_color(1, len, CV_32F);
|
||||
|
||||
@ -85,7 +113,7 @@ namespace
|
||||
table_color.upload(cpu_table_color);
|
||||
}
|
||||
|
||||
inline void calc_space_weighted_filter(GpuMat& table_space, int win_size, float dist_space)
|
||||
void calc_space_weighted_filter(GpuMat& table_space, int win_size, float dist_space)
|
||||
{
|
||||
int half = (win_size >> 1);
|
||||
|
||||
@ -101,54 +129,78 @@ namespace
|
||||
table_space.upload(cpu_table_space);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void disp_bilateral_filter_operator(int ndisp, int radius, int iters, float edge_threshold,float max_disc_threshold,
|
||||
GpuMat& table_color, GpuMat& table_space,
|
||||
const GpuMat& disp, const GpuMat& img, GpuMat& dst, Stream& stream)
|
||||
const float DEFAULT_EDGE_THRESHOLD = 0.1f;
|
||||
const float DEFAULT_MAX_DISC_THRESHOLD = 0.2f;
|
||||
const float DEFAULT_SIGMA_RANGE = 10.0f;
|
||||
|
||||
DispBilateralFilterImpl::DispBilateralFilterImpl(int ndisp, int radius, int iters) :
|
||||
ndisp_(ndisp), radius_(radius), iters_(iters),
|
||||
edge_threshold_(DEFAULT_EDGE_THRESHOLD), max_disc_threshold_(DEFAULT_MAX_DISC_THRESHOLD),
|
||||
sigma_range_(DEFAULT_SIGMA_RANGE)
|
||||
{
|
||||
short edge_disc = std::max<short>(short(1), short(ndisp * edge_threshold + 0.5));
|
||||
short max_disc = short(ndisp * max_disc_threshold + 0.5);
|
||||
calc_color_weighted_table(table_color_, sigma_range_, 255);
|
||||
calc_space_weighted_filter(table_space_, radius_ * 2 + 1, radius_ + 1.0f);
|
||||
}
|
||||
|
||||
void DispBilateralFilterImpl::setRadius(int radius)
|
||||
{
|
||||
radius_ = radius;
|
||||
calc_space_weighted_filter(table_space_, radius_ * 2 + 1, radius_ + 1.0f);
|
||||
}
|
||||
|
||||
void DispBilateralFilterImpl::setSigmaRange(double sigma_range)
|
||||
{
|
||||
sigma_range_ = (float) sigma_range;
|
||||
calc_color_weighted_table(table_color_, sigma_range_, 255);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void disp_bilateral_filter_operator(int ndisp, int radius, int iters, float edge_threshold, float max_disc_threshold,
|
||||
GpuMat& table_color, GpuMat& table_space,
|
||||
const GpuMat& disp, const GpuMat& img,
|
||||
OutputArray _dst, Stream& stream)
|
||||
{
|
||||
using namespace cv::gpu::cudev::disp_bilateral_filter;
|
||||
|
||||
const short edge_disc = std::max<short>(short(1), short(ndisp * edge_threshold + 0.5));
|
||||
const short max_disc = short(ndisp * max_disc_threshold + 0.5);
|
||||
|
||||
disp_load_constants(table_color.ptr<float>(), table_space, ndisp, radius, edge_disc, max_disc);
|
||||
|
||||
if (&dst != &disp)
|
||||
{
|
||||
_dst.create(disp.size(), disp.type());
|
||||
GpuMat dst = _dst.getGpuMat();
|
||||
|
||||
if (dst.data != disp.data)
|
||||
disp.copyTo(dst, stream);
|
||||
}
|
||||
|
||||
disp_bilateral_filter<T>(dst, img, img.channels(), iters, StreamAccessor::getStream(stream));
|
||||
}
|
||||
|
||||
typedef void (*bilateral_filter_operator_t)(int ndisp, int radius, int iters, float edge_threshold, float max_disc_threshold,
|
||||
GpuMat& table_color, GpuMat& table_space,
|
||||
const GpuMat& disp, const GpuMat& img, GpuMat& dst, Stream& stream);
|
||||
void DispBilateralFilterImpl::apply(InputArray _disp, InputArray _image, OutputArray dst, Stream& stream)
|
||||
{
|
||||
typedef void (*bilateral_filter_operator_t)(int ndisp, int radius, int iters, float edge_threshold, float max_disc_threshold,
|
||||
GpuMat& table_color, GpuMat& table_space,
|
||||
const GpuMat& disp, const GpuMat& img, OutputArray dst, Stream& stream);
|
||||
const bilateral_filter_operator_t operators[] =
|
||||
{disp_bilateral_filter_operator<unsigned char>, 0, 0, disp_bilateral_filter_operator<short>, 0, 0, 0, 0};
|
||||
|
||||
const bilateral_filter_operator_t operators[] =
|
||||
{disp_bilateral_filter_operator<unsigned char>, 0, 0, disp_bilateral_filter_operator<short>, 0, 0, 0, 0};
|
||||
CV_Assert( 0 < ndisp_ && 0 < radius_ && 0 < iters_ );
|
||||
|
||||
GpuMat disp = _disp.getGpuMat();
|
||||
GpuMat img = _image.getGpuMat();
|
||||
|
||||
CV_Assert( disp.type() == CV_8U || disp.type() == CV_16S );
|
||||
CV_Assert( img.type() == CV_8UC1 || img.type() == CV_8UC3 );
|
||||
CV_Assert( disp.size() == img.size() );
|
||||
|
||||
operators[disp.type()](ndisp_, radius_, iters_, edge_threshold_, max_disc_threshold_,
|
||||
table_color_, table_space_, disp, img, dst, stream);
|
||||
}
|
||||
}
|
||||
|
||||
cv::gpu::DisparityBilateralFilter::DisparityBilateralFilter(int ndisp_, int radius_, int iters_)
|
||||
: ndisp(ndisp_), radius(radius_), iters(iters_), edge_threshold(DEFAULT_EDGE_THRESHOLD), max_disc_threshold(DEFAULT_MAX_DISC_THRESHOLD),
|
||||
sigma_range(DEFAULT_SIGMA_RANGE)
|
||||
Ptr<gpu::DisparityBilateralFilter> cv::gpu::createDisparityBilateralFilter(int ndisp, int radius, int iters)
|
||||
{
|
||||
calc_color_weighted_table(table_color, sigma_range, 255);
|
||||
calc_space_weighted_filter(table_space, radius * 2 + 1, radius + 1.0f);
|
||||
}
|
||||
|
||||
cv::gpu::DisparityBilateralFilter::DisparityBilateralFilter(int ndisp_, int radius_, int iters_, float edge_threshold_,
|
||||
float max_disc_threshold_, float sigma_range_)
|
||||
: ndisp(ndisp_), radius(radius_), iters(iters_), edge_threshold(edge_threshold_), max_disc_threshold(max_disc_threshold_),
|
||||
sigma_range(sigma_range_)
|
||||
{
|
||||
calc_color_weighted_table(table_color, sigma_range, 255);
|
||||
calc_space_weighted_filter(table_space, radius * 2 + 1, radius + 1.0f);
|
||||
}
|
||||
|
||||
void cv::gpu::DisparityBilateralFilter::operator()(const GpuMat& disp, const GpuMat& img, GpuMat& dst, Stream& stream)
|
||||
{
|
||||
CV_DbgAssert(0 < ndisp && 0 < radius && 0 < iters);
|
||||
CV_Assert(disp.rows == img.rows && disp.cols == img.cols && (disp.type() == CV_8U || disp.type() == CV_16S) && (img.type() == CV_8UC1 || img.type() == CV_8UC3));
|
||||
operators[disp.type()](ndisp, radius, iters, edge_threshold, max_disc_threshold, table_color, table_space, disp, img, dst, stream);
|
||||
return new DispBilateralFilterImpl(ndisp, radius, iters);
|
||||
}
|
||||
|
||||
#endif /* !defined (HAVE_CUDA) */
|
||||
|
Loading…
x
Reference in New Issue
Block a user