refactored DisparityBilateralFilter
This commit is contained in:
parent
be9bb8f18b
commit
3a02e599e0
@ -134,44 +134,48 @@ public:
|
|||||||
CV_EXPORTS Ptr<gpu::StereoConstantSpaceBP>
|
CV_EXPORTS Ptr<gpu::StereoConstantSpaceBP>
|
||||||
createStereoConstantSpaceBP(int ndisp = 128, int iters = 8, int levels = 4, int nr_plane = 4, int msg_type = CV_32F);
|
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
|
||||||
// Disparity map refinement using joint bilateral filtering given a single color image.
|
//! http://vision.ai.uiuc.edu/~qyang6/
|
||||||
// Qingxiong Yang, Liang Wang, Narendra Ahuja
|
class CV_EXPORTS DisparityBilateralFilter : public cv::Algorithm
|
||||||
// http://vision.ai.uiuc.edu/~qyang6/
|
|
||||||
class CV_EXPORTS DisparityBilateralFilter
|
|
||||||
{
|
{
|
||||||
public:
|
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.
|
//! 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.
|
//! 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:
|
virtual int getNumDisparities() const = 0;
|
||||||
int ndisp;
|
virtual void setNumDisparities(int numDisparities) = 0;
|
||||||
int radius;
|
|
||||||
int iters;
|
|
||||||
|
|
||||||
float edge_threshold;
|
virtual int getRadius() const = 0;
|
||||||
float max_disc_threshold;
|
virtual void setRadius(int radius) = 0;
|
||||||
float sigma_range;
|
|
||||||
|
|
||||||
GpuMat table_color;
|
virtual int getNumIters() const = 0;
|
||||||
GpuMat table_space;
|
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.
|
//! Reprojects disparity image to 3D space.
|
||||||
//! Supports CV_8U and CV_16S types of input disparity.
|
//! Supports CV_8U and CV_16S types of input disparity.
|
||||||
//! The output is a 3- or 4-channel floating-point matrix.
|
//! The output is a 3- or 4-channel floating-point matrix.
|
||||||
|
@ -173,13 +173,13 @@ PERF_TEST_P(ImagePair, DisparityBilateralFilter,
|
|||||||
|
|
||||||
if (PERF_RUN_GPU())
|
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_img(img);
|
||||||
const cv::gpu::GpuMat d_disp(disp);
|
const cv::gpu::GpuMat d_disp(disp);
|
||||||
cv::gpu::GpuMat dst;
|
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);
|
GPU_SANITY_CHECK(dst);
|
||||||
}
|
}
|
||||||
|
@ -47,10 +47,7 @@ using namespace cv::gpu;
|
|||||||
|
|
||||||
#if !defined (HAVE_CUDA) || defined (CUDA_DISABLER)
|
#if !defined (HAVE_CUDA) || defined (CUDA_DISABLER)
|
||||||
|
|
||||||
cv::gpu::DisparityBilateralFilter::DisparityBilateralFilter(int, int, int) { throw_no_cuda(); }
|
Ptr<gpu::DisparityBilateralFilter> cv::gpu::createDisparityBilateralFilter(int, int, int) { throw_no_cuda(); return Ptr<gpu::DisparityBilateralFilter>(); }
|
||||||
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(); }
|
|
||||||
|
|
||||||
#else /* !defined (HAVE_CUDA) */
|
#else /* !defined (HAVE_CUDA) */
|
||||||
|
|
||||||
@ -65,15 +62,46 @@ namespace cv { namespace gpu { namespace cudev
|
|||||||
}
|
}
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
using namespace ::cv::gpu::cudev::disp_bilateral_filter;
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
const float DEFAULT_EDGE_THRESHOLD = 0.1f;
|
class DispBilateralFilterImpl : public gpu::DisparityBilateralFilter
|
||||||
const float DEFAULT_MAX_DISC_THRESHOLD = 0.2f;
|
{
|
||||||
const float DEFAULT_SIGMA_RANGE = 10.0f;
|
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);
|
Mat cpu_table_color(1, len, CV_32F);
|
||||||
|
|
||||||
@ -85,7 +113,7 @@ namespace
|
|||||||
table_color.upload(cpu_table_color);
|
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);
|
int half = (win_size >> 1);
|
||||||
|
|
||||||
@ -101,54 +129,78 @@ namespace
|
|||||||
table_space.upload(cpu_table_space);
|
table_space.upload(cpu_table_space);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
const float DEFAULT_EDGE_THRESHOLD = 0.1f;
|
||||||
void disp_bilateral_filter_operator(int ndisp, int radius, int iters, float edge_threshold,float max_disc_threshold,
|
const float DEFAULT_MAX_DISC_THRESHOLD = 0.2f;
|
||||||
GpuMat& table_color, GpuMat& table_space,
|
const float DEFAULT_SIGMA_RANGE = 10.0f;
|
||||||
const GpuMat& disp, const GpuMat& img, GpuMat& dst, Stream& stream)
|
|
||||||
|
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));
|
calc_color_weighted_table(table_color_, sigma_range_, 255);
|
||||||
short max_disc = short(ndisp * max_disc_threshold + 0.5);
|
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);
|
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.copyTo(dst, stream);
|
||||||
}
|
|
||||||
|
|
||||||
disp_bilateral_filter<T>(dst, img, img.channels(), iters, StreamAccessor::getStream(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,
|
void DispBilateralFilterImpl::apply(InputArray _disp, InputArray _image, OutputArray dst, Stream& stream)
|
||||||
GpuMat& table_color, GpuMat& table_space,
|
{
|
||||||
const GpuMat& disp, const GpuMat& img, GpuMat& 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[] =
|
CV_Assert( 0 < ndisp_ && 0 < radius_ && 0 < iters_ );
|
||||||
{disp_bilateral_filter_operator<unsigned char>, 0, 0, disp_bilateral_filter_operator<short>, 0, 0, 0, 0};
|
|
||||||
|
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_)
|
Ptr<gpu::DisparityBilateralFilter> cv::gpu::createDisparityBilateralFilter(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)
|
|
||||||
{
|
{
|
||||||
calc_color_weighted_table(table_color, sigma_range, 255);
|
return new DispBilateralFilterImpl(ndisp, radius, iters);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !defined (HAVE_CUDA) */
|
#endif /* !defined (HAVE_CUDA) */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user