|
|
|
@ -58,7 +58,6 @@ void cv::gpu::DisparityBilateralFilter::operator()(const GpuMat&, const GpuMat&, |
|
|
|
|
|
|
|
|
|
namespace cv { namespace gpu { namespace bf
|
|
|
|
|
{ |
|
|
|
|
void calc_space_weighted_filter_gpu(const DevMem2Df& table_space, int half, float dist_space, cudaStream_t stream); |
|
|
|
|
void load_constants(float* table_color, const DevMem2Df& table_space, int ndisp, int radius, short edge_disc, short max_disc); |
|
|
|
|
|
|
|
|
|
void bilateral_filter_gpu(const DevMem2D& disp, const DevMem2D& img, int channels, int iters, cudaStream_t stream); |
|
|
|
@ -71,50 +70,53 @@ namespace |
|
|
|
|
const float DEFAULT_MAX_DISC_THRESHOLD = 0.2f; |
|
|
|
|
const float DEFAULT_SIGMA_RANGE = 10.0f; |
|
|
|
|
|
|
|
|
|
inline void calc_color_weighted_table(vector<float>& table_color, float sigma_range, int len) |
|
|
|
|
inline void calc_color_weighted_table(GpuMat& table_color, float sigma_range, int len) |
|
|
|
|
{ |
|
|
|
|
float* color_table_x; |
|
|
|
|
|
|
|
|
|
table_color.resize(len); |
|
|
|
|
color_table_x = &table_color[0]; |
|
|
|
|
Mat cpu_table_color(1, len, CV_32F); |
|
|
|
|
|
|
|
|
|
for(int y = 0; y < len; y++)
|
|
|
|
|
table_color[y] = static_cast<float>(std::exp(-double(y * y) / (2 * sigma_range * sigma_range))); |
|
|
|
|
float* line = cpu_table_color.ptr<float>(); |
|
|
|
|
|
|
|
|
|
for(int i = 0; i < len; i++)
|
|
|
|
|
line[i] = static_cast<float>(std::exp(-double(i * i) / (2 * sigma_range * sigma_range))); |
|
|
|
|
|
|
|
|
|
table_color.upload(cpu_table_color); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline void calc_space_weighted_filter(GpuMat& table_space, int win_size, float dist_space, cudaStream_t stream) |
|
|
|
|
inline void calc_space_weighted_filter(GpuMat& table_space, int win_size, float dist_space) |
|
|
|
|
{ |
|
|
|
|
int half = (win_size >> 1); |
|
|
|
|
table_space.create(half + 1, half + 1, CV_32F); |
|
|
|
|
|
|
|
|
|
bf::calc_space_weighted_filter_gpu(table_space, half, dist_space, stream); |
|
|
|
|
Mat cpu_table_space(half + 1, half + 1, CV_32F); |
|
|
|
|
|
|
|
|
|
for (int y = 0; y <= half; ++y) |
|
|
|
|
{ |
|
|
|
|
float* row = cpu_table_space.ptr<float>(y); |
|
|
|
|
for (int x = 0; x <= half; ++x) |
|
|
|
|
row[x] = exp(-sqrt(float(y * y) + float(x * x)) / dist_space); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
table_space.upload(cpu_table_space); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <typename T> |
|
|
|
|
void bilateral_filter_operator(DisparityBilateralFilter& rthis, vector<float>& table_color, GpuMat& table_space,
|
|
|
|
|
void 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, cudaStream_t stream) |
|
|
|
|
{ |
|
|
|
|
calc_color_weighted_table(table_color, rthis.sigma_range, 255); |
|
|
|
|
calc_space_weighted_filter(table_space, rthis.radius * 2 + 1, rthis.radius + 1.0f, stream); |
|
|
|
|
|
|
|
|
|
short edge_disc = max<short>(short(1), short(rthis.ndisp * rthis.edge_threshold + 0.5)); |
|
|
|
|
short max_disc = short(rthis.ndisp * rthis.max_disc_threshold + 0.5); |
|
|
|
|
short edge_disc = max<short>(short(1), short(ndisp * edge_threshold + 0.5)); |
|
|
|
|
short max_disc = short(ndisp * max_disc_threshold + 0.5); |
|
|
|
|
|
|
|
|
|
float* table_color_dev; |
|
|
|
|
cudaSafeCall( cudaMalloc((void**)&table_color_dev, table_color.size() * sizeof(float)) ); |
|
|
|
|
cudaSafeCall( cudaMemcpy(table_color_dev, &table_color[0], table_color.size() * sizeof(float), cudaMemcpyHostToDevice) ); |
|
|
|
|
bf::load_constants(table_color_dev, table_space, rthis.ndisp, rthis.radius, edge_disc, max_disc); |
|
|
|
|
bf::load_constants(table_color.ptr<float>(), table_space, ndisp, radius, edge_disc, max_disc); |
|
|
|
|
|
|
|
|
|
if (&dst != &disp) |
|
|
|
|
disp.copyTo(dst); |
|
|
|
|
|
|
|
|
|
bf::bilateral_filter_gpu((DevMem2D_<T>)dst, img, img.channels(), rthis.iters, stream); |
|
|
|
|
|
|
|
|
|
cudaSafeCall( cudaFree(table_color_dev) ); |
|
|
|
|
bf::bilateral_filter_gpu((DevMem2D_<T>)dst, img, img.channels(), iters, stream); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
typedef void (*bilateral_filter_operator_t)(DisparityBilateralFilter& rthis, vector<float>& table_color, GpuMat& table_space,
|
|
|
|
|
const GpuMat& disp, const GpuMat& img, GpuMat& dst, cudaStream_t 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, cudaStream_t stream); |
|
|
|
|
|
|
|
|
|
const bilateral_filter_operator_t operators[] =
|
|
|
|
|
{bilateral_filter_operator<unsigned char>, 0, 0, bilateral_filter_operator<short>, 0, 0, 0, 0}; |
|
|
|
@ -124,6 +126,8 @@ cv::gpu::DisparityBilateralFilter::DisparityBilateralFilter(int ndisp_, int radi |
|
|
|
|
: 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); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
cv::gpu::DisparityBilateralFilter::DisparityBilateralFilter(int ndisp_, int radius_, int iters_, float edge_threshold_,
|
|
|
|
@ -131,20 +135,22 @@ cv::gpu::DisparityBilateralFilter::DisparityBilateralFilter(int ndisp_, int radi |
|
|
|
|
: 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) |
|
|
|
|
{ |
|
|
|
|
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()](*this, table_color, table_space, disp, img, dst, 0); |
|
|
|
|
operators[disp.type()](ndisp, radius, iters, edge_threshold, max_disc_threshold, table_color, table_space, disp, img, dst, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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()](*this, table_color, table_space, disp, img, dst, StreamAccessor::getStream(stream)); |
|
|
|
|
operators[disp.type()](ndisp, radius, iters, edge_threshold, max_disc_threshold, table_color, table_space, disp, img, dst, StreamAccessor::getStream(stream)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif /* !defined (HAVE_CUDA) */ |
|
|
|
|