fast_nlm initial version
This commit is contained in:
@@ -49,9 +49,12 @@ using namespace cv::gpu;
|
||||
|
||||
void cv::gpu::bilateralFilter(const GpuMat&, GpuMat&, int, float, float, int, Stream&) { throw_nogpu(); }
|
||||
void cv::gpu::nonLocalMeans(const GpuMat&, GpuMat&, float, int, int, int, Stream&) { throw_nogpu(); }
|
||||
void cv::gpu::fastNlMeansDenoising( const GpuMat&, GpuMat&, float, int, int, Stream&) { throw_nogpu(); }
|
||||
|
||||
#else
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
//// Non Local Means Denosing (brute force)
|
||||
|
||||
namespace cv { namespace gpu { namespace device
|
||||
{
|
||||
@@ -106,9 +109,9 @@ void cv::gpu::nonLocalMeans(const GpuMat& src, GpuMat& dst, float h, int search_
|
||||
using cv::gpu::device::imgproc::nlm_bruteforce_gpu;
|
||||
typedef void (*func_t)(const PtrStepSzb& src, PtrStepSzb dst, int search_radius, int block_radius, float h, int borderMode, cudaStream_t stream);
|
||||
|
||||
static const func_t funcs[4] = { nlm_bruteforce_gpu<uchar>, 0 /*nlm_bruteforce_gpu<uchar2>*/ , nlm_bruteforce_gpu<uchar3>, 0/*nlm_bruteforce_gpu<uchar4>,*/ };
|
||||
static const func_t funcs[4] = { nlm_bruteforce_gpu<uchar>, nlm_bruteforce_gpu<uchar2>, nlm_bruteforce_gpu<uchar3>, 0/*nlm_bruteforce_gpu<uchar4>,*/ };
|
||||
|
||||
CV_Assert(src.type() == CV_8U || src.type() == CV_8UC3);
|
||||
CV_Assert(src.type() == CV_8U || src.type() == CV_8UC2 || src.type() == CV_8UC3);
|
||||
|
||||
const func_t func = funcs[src.channels() - 1];
|
||||
CV_Assert(func != 0);
|
||||
@@ -127,10 +130,235 @@ void cv::gpu::nonLocalMeans(const GpuMat& src, GpuMat& dst, float h, int search_
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
//// Non Local Means Denosing (fast approxinate)
|
||||
|
||||
|
||||
namespace cv { namespace gpu { namespace device
|
||||
{
|
||||
namespace imgproc
|
||||
{
|
||||
void nln_fast_get_buffer_size(const PtrStepSzb& src, int search_window, int block_window, int& buffer_cols, int& buffer_rows);
|
||||
|
||||
template<typename T>
|
||||
void nlm_fast_gpu(const PtrStepSzb& src, PtrStepSzb dst, PtrStepi buffer,
|
||||
int search_window, int block_window, float h, cudaStream_t stream);
|
||||
|
||||
}
|
||||
}}}
|
||||
|
||||
|
||||
|
||||
//class CV_EXPORTS FastNonLocalMeansDenoising
|
||||
//{
|
||||
//public:
|
||||
// FastNonLocalMeansDenoising(float h, int search_radius, int block_radius, const Size& image_size = Size())
|
||||
// {
|
||||
// if (size.area() != 0)
|
||||
// allocate_buffers(image_size);
|
||||
// }
|
||||
|
||||
// void operator()(const GpuMat& src, GpuMat& dst);
|
||||
|
||||
//private:
|
||||
// void allocate_buffers(const Size& image_size)
|
||||
// {
|
||||
// col_dist_sums.create(block_window_, search_window_ * search_window_, CV_32S);
|
||||
// up_col_dist_sums.create(image_size.width, search_window_ * search_window_, CV_32S);
|
||||
// }
|
||||
|
||||
// int search_radius_;
|
||||
// int block_radius;
|
||||
// GpuMat col_dist_sums_;
|
||||
// GpuMat up_col_dist_sums_;
|
||||
//};
|
||||
|
||||
void cv::gpu::fastNlMeansDenoising( const GpuMat& src, GpuMat& dst, float h, int search_radius, int block_radius, Stream& s)
|
||||
{
|
||||
dst.create(src.size(), src.type());
|
||||
CV_Assert(src.depth() == CV_8U && src.channels() < 4);
|
||||
|
||||
GpuMat extended_src, src_hdr;
|
||||
int border_size = search_radius + block_radius;
|
||||
cv::gpu::copyMakeBorder(src, extended_src, border_size, border_size, border_size, border_size, cv::BORDER_DEFAULT, Scalar(), s);
|
||||
src_hdr = extended_src(Rect(Point2i(border_size, border_size), src.size()));
|
||||
|
||||
using namespace cv::gpu::device::imgproc;
|
||||
typedef void (*nlm_fast_t)(const PtrStepSzb&, PtrStepSzb, PtrStepi, int, int, float, cudaStream_t);
|
||||
static const nlm_fast_t funcs[] = { nlm_fast_gpu<uchar>, nlm_fast_gpu<uchar2>, nlm_fast_gpu<uchar3>, 0 };
|
||||
|
||||
int search_window = 2 * search_radius + 1;
|
||||
int block_window = 2 * block_radius + 1;
|
||||
|
||||
int bcols, brows;
|
||||
nln_fast_get_buffer_size(src_hdr, search_window, block_window, bcols, brows);
|
||||
|
||||
//GpuMat col_dist_sums(block_window * gx, search_window * search_window * gy, CV_32S);
|
||||
//GpuMat up_col_dist_sums(src.cols, search_window * search_window * gy, CV_32S);
|
||||
GpuMat buffer(brows, bcols, CV_32S);
|
||||
|
||||
funcs[src.channels()-1](src_hdr, dst, buffer, search_window, block_window, h, StreamAccessor::getStream(s));
|
||||
}
|
||||
|
||||
//void cv::gpu::fastNlMeansDenoisingColored( const GpuMat& src, GpuMat& dst, float h, float hForColorComponents, int templateWindowSize, int searchWindowSize)
|
||||
//{
|
||||
// Mat src = _src.getMat();
|
||||
// _dst.create(src.size(), src.type());
|
||||
// Mat dst = _dst.getMat();
|
||||
|
||||
// if (src.type() != CV_8UC3) {
|
||||
// CV_Error(CV_StsBadArg, "Type of input image should be CV_8UC3!");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Mat src_lab;
|
||||
// cvtColor(src, src_lab, CV_LBGR2Lab);
|
||||
|
||||
// Mat l(src.size(), CV_8U);
|
||||
// Mat ab(src.size(), CV_8UC2);
|
||||
// Mat l_ab[] = { l, ab };
|
||||
// int from_to[] = { 0,0, 1,1, 2,2 };
|
||||
// mixChannels(&src_lab, 1, l_ab, 2, from_to, 3);
|
||||
|
||||
// fastNlMeansDenoising(l, l, h, templateWindowSize, searchWindowSize);
|
||||
// fastNlMeansDenoising(ab, ab, hForColorComponents, templateWindowSize, searchWindowSize);
|
||||
|
||||
// Mat l_ab_denoised[] = { l, ab };
|
||||
// Mat dst_lab(src.size(), src.type());
|
||||
// mixChannels(l_ab_denoised, 2, &dst_lab, 1, from_to, 3);
|
||||
|
||||
// cvtColor(dst_lab, dst, CV_Lab2LBGR);
|
||||
//}
|
||||
|
||||
//static void fastNlMeansDenoisingMultiCheckPreconditions(
|
||||
// const std::vector<Mat>& srcImgs,
|
||||
// int imgToDenoiseIndex, int temporalWindowSize,
|
||||
// int templateWindowSize, int searchWindowSize)
|
||||
//{
|
||||
// int src_imgs_size = (int)srcImgs.size();
|
||||
// if (src_imgs_size == 0) {
|
||||
// CV_Error(CV_StsBadArg, "Input images vector should not be empty!");
|
||||
// }
|
||||
|
||||
// if (temporalWindowSize % 2 == 0 ||
|
||||
// searchWindowSize % 2 == 0 ||
|
||||
// templateWindowSize % 2 == 0) {
|
||||
// CV_Error(CV_StsBadArg, "All windows sizes should be odd!");
|
||||
// }
|
||||
|
||||
// int temporalWindowHalfSize = temporalWindowSize / 2;
|
||||
// if (imgToDenoiseIndex - temporalWindowHalfSize < 0 ||
|
||||
// imgToDenoiseIndex + temporalWindowHalfSize >= src_imgs_size)
|
||||
// {
|
||||
// CV_Error(CV_StsBadArg,
|
||||
// "imgToDenoiseIndex and temporalWindowSize "
|
||||
// "should be choosen corresponding srcImgs size!");
|
||||
// }
|
||||
|
||||
// for (int i = 1; i < src_imgs_size; i++) {
|
||||
// if (srcImgs[0].size() != srcImgs[i].size() || srcImgs[0].type() != srcImgs[i].type()) {
|
||||
// CV_Error(CV_StsBadArg, "Input images should have the same size and type!");
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
//void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _dst,
|
||||
// int imgToDenoiseIndex, int temporalWindowSize,
|
||||
// float h, int templateWindowSize, int searchWindowSize)
|
||||
//{
|
||||
// vector<Mat> srcImgs;
|
||||
// _srcImgs.getMatVector(srcImgs);
|
||||
|
||||
// fastNlMeansDenoisingMultiCheckPreconditions(
|
||||
// srcImgs, imgToDenoiseIndex,
|
||||
// temporalWindowSize, templateWindowSize, searchWindowSize
|
||||
// );
|
||||
// _dst.create(srcImgs[0].size(), srcImgs[0].type());
|
||||
// Mat dst = _dst.getMat();
|
||||
|
||||
// switch (srcImgs[0].type()) {
|
||||
// case CV_8U:
|
||||
// parallel_for(cv::BlockedRange(0, srcImgs[0].rows),
|
||||
// FastNlMeansMultiDenoisingInvoker<uchar>(
|
||||
// srcImgs, imgToDenoiseIndex, temporalWindowSize,
|
||||
// dst, templateWindowSize, searchWindowSize, h));
|
||||
// break;
|
||||
// case CV_8UC2:
|
||||
// parallel_for(cv::BlockedRange(0, srcImgs[0].rows),
|
||||
// FastNlMeansMultiDenoisingInvoker<cv::Vec2b>(
|
||||
// srcImgs, imgToDenoiseIndex, temporalWindowSize,
|
||||
// dst, templateWindowSize, searchWindowSize, h));
|
||||
// break;
|
||||
// case CV_8UC3:
|
||||
// parallel_for(cv::BlockedRange(0, srcImgs[0].rows),
|
||||
// FastNlMeansMultiDenoisingInvoker<cv::Vec3b>(
|
||||
// srcImgs, imgToDenoiseIndex, temporalWindowSize,
|
||||
// dst, templateWindowSize, searchWindowSize, h));
|
||||
// break;
|
||||
// default:
|
||||
// CV_Error(CV_StsBadArg,
|
||||
// "Unsupported matrix format! Only uchar, Vec2b, Vec3b are supported");
|
||||
// }
|
||||
//}
|
||||
|
||||
//void cv::fastNlMeansDenoisingColoredMulti( InputArrayOfArrays _srcImgs, OutputArray _dst,
|
||||
// int imgToDenoiseIndex, int temporalWindowSize,
|
||||
// float h, float hForColorComponents,
|
||||
// int templateWindowSize, int searchWindowSize)
|
||||
//{
|
||||
// vector<Mat> srcImgs;
|
||||
// _srcImgs.getMatVector(srcImgs);
|
||||
|
||||
// fastNlMeansDenoisingMultiCheckPreconditions(
|
||||
// srcImgs, imgToDenoiseIndex,
|
||||
// temporalWindowSize, templateWindowSize, searchWindowSize
|
||||
// );
|
||||
|
||||
// _dst.create(srcImgs[0].size(), srcImgs[0].type());
|
||||
// Mat dst = _dst.getMat();
|
||||
|
||||
// int src_imgs_size = (int)srcImgs.size();
|
||||
|
||||
// if (srcImgs[0].type() != CV_8UC3) {
|
||||
// CV_Error(CV_StsBadArg, "Type of input images should be CV_8UC3!");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// int from_to[] = { 0,0, 1,1, 2,2 };
|
||||
|
||||
// // TODO convert only required images
|
||||
// vector<Mat> src_lab(src_imgs_size);
|
||||
// vector<Mat> l(src_imgs_size);
|
||||
// vector<Mat> ab(src_imgs_size);
|
||||
// for (int i = 0; i < src_imgs_size; i++) {
|
||||
// src_lab[i] = Mat::zeros(srcImgs[0].size(), CV_8UC3);
|
||||
// l[i] = Mat::zeros(srcImgs[0].size(), CV_8UC1);
|
||||
// ab[i] = Mat::zeros(srcImgs[0].size(), CV_8UC2);
|
||||
// cvtColor(srcImgs[i], src_lab[i], CV_LBGR2Lab);
|
||||
|
||||
// Mat l_ab[] = { l[i], ab[i] };
|
||||
// mixChannels(&src_lab[i], 1, l_ab, 2, from_to, 3);
|
||||
// }
|
||||
|
||||
// Mat dst_l;
|
||||
// Mat dst_ab;
|
||||
|
||||
// fastNlMeansDenoisingMulti(
|
||||
// l, dst_l, imgToDenoiseIndex, temporalWindowSize,
|
||||
// h, templateWindowSize, searchWindowSize);
|
||||
|
||||
// fastNlMeansDenoisingMulti(
|
||||
// ab, dst_ab, imgToDenoiseIndex, temporalWindowSize,
|
||||
// hForColorComponents, templateWindowSize, searchWindowSize);
|
||||
|
||||
// Mat l_ab_denoised[] = { dst_l, dst_ab };
|
||||
// Mat dst_lab(srcImgs[0].size(), srcImgs[0].type());
|
||||
// mixChannels(l_ab_denoised, 2, &dst_lab, 1, from_to, 3);
|
||||
|
||||
// cvtColor(dst_lab, dst, CV_Lab2LBGR);
|
||||
//}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user