|
|
|
@ -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); |
|
|
|
|
|
|
|
|
|
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; } |
|
|
|
|
|
|
|
|
|
inline void calc_color_weighted_table(GpuMat& table_color, float sigma_range, int len) |
|
|
|
|
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); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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) |
|
|
|
|
{ |
|
|
|
|
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, GpuMat& dst, Stream& stream) |
|
|
|
|
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) |
|
|
|
|
{ |
|
|
|
|
short edge_disc = std::max<short>(short(1), short(ndisp * edge_threshold + 0.5)); |
|
|
|
|
short max_disc = short(ndisp * max_disc_threshold + 0.5); |
|
|
|
|
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_ ); |
|
|
|
|
|
|
|
|
|
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) |
|
|
|
|
{ |
|
|
|
|
calc_color_weighted_table(table_color, sigma_range, 255); |
|
|
|
|
calc_space_weighted_filter(table_space, radius * 2 + 1, radius + 1.0f); |
|
|
|
|
} |
|
|
|
|
GpuMat disp = _disp.getGpuMat(); |
|
|
|
|
GpuMat img = _image.getGpuMat(); |
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
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); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void cv::gpu::DisparityBilateralFilter::operator()(const GpuMat& disp, const GpuMat& img, GpuMat& dst, Stream& stream) |
|
|
|
|
Ptr<gpu::DisparityBilateralFilter> cv::gpu::createDisparityBilateralFilter(int ndisp, int radius, int iters) |
|
|
|
|
{ |
|
|
|
|
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) */ |
|
|
|
|