1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 15:23:05 +04:00

Merge pull request #18167 from Yosshi999:bit-exact-gaussian

Bit exact gaussian blur for 16bit unsigned int

* bit-exact gaussian kernel for CV_16U

* SIMD optimization

* template GaussianBlurFixedPoint

* remove template specialization

* simd support for h3N121 uint16

* test for u16 gaussian blur

* remove unnecessary comments

* fix return type of raw()

* add typedef of native internal type in fixedpoint

* update return type of raw()
This commit is contained in:
Yosshi999
2020-09-01 19:28:25 +09:00
committed by GitHub
parent 1d42560018
commit 698b2bf729
4 changed files with 265 additions and 122 deletions
+40 -6
View File
@@ -258,23 +258,20 @@ softdouble getGaussianKernelFixedPoint_ED(CV_OUT std::vector<int64_t>& result, c
}
static void getGaussianKernel(int n, double sigma, int ktype, Mat& res) { res = getGaussianKernel(n, sigma, ktype); }
template <typename T> static void getGaussianKernel(int n, double sigma, int, std::vector<T>& res);
//{ res = getFixedpointGaussianKernel<T>(n, sigma); }
template<> void getGaussianKernel<ufixedpoint16>(int n, double sigma, int, std::vector<ufixedpoint16>& res)
template <typename FT> static void getGaussianKernel(int n, double sigma, int, std::vector<FT>& res)
{
std::vector<softdouble> res_sd;
softdouble s0 = getGaussianKernelBitExact(res_sd, n, sigma);
CV_UNUSED(s0);
std::vector<int64_t> fixed_256;
softdouble approx_err = getGaussianKernelFixedPoint_ED(fixed_256, res_sd, 8);
softdouble approx_err = getGaussianKernelFixedPoint_ED(fixed_256, res_sd, FT::fixedShift);
CV_UNUSED(approx_err);
res.resize(n);
for (int i = 0; i < n; i++)
{
res[i] = ufixedpoint16::fromRaw((uint16_t)fixed_256[i]);
res[i] = FT::fromRaw((typename FT::raw_t)fixed_256[i]);
//printf("%03d: %d\n", i, res[i].raw());
}
}
@@ -688,6 +685,43 @@ void GaussianBlur(InputArray _src, OutputArray _dst, Size ksize,
return;
}
}
if(sdepth == CV_16U && ((borderType & BORDER_ISOLATED) || !_src.isSubmatrix()))
{
CV_LOG_INFO(NULL, "GaussianBlur: running bit-exact version...");
std::vector<ufixedpoint32> fkx, fky;
createGaussianKernels(fkx, fky, type, ksize, sigma1, sigma2);
static bool param_check_gaussian_blur_bitexact_kernels = utils::getConfigurationParameterBool("OPENCV_GAUSSIANBLUR_CHECK_BITEXACT_KERNELS", false);
if (param_check_gaussian_blur_bitexact_kernels && !validateGaussianBlurKernel(fkx))
{
CV_LOG_INFO(NULL, "GaussianBlur: bit-exact fx kernel can't be applied: ksize=" << ksize << " sigma=" << Size2d(sigma1, sigma2));
}
else if (param_check_gaussian_blur_bitexact_kernels && !validateGaussianBlurKernel(fky))
{
CV_LOG_INFO(NULL, "GaussianBlur: bit-exact fy kernel can't be applied: ksize=" << ksize << " sigma=" << Size2d(sigma1, sigma2));
}
else
{
// TODO: implement ocl_sepFilter2D_BitExact -- how to deal with bdepth?
// CV_OCL_RUN(useOpenCL,
// ocl_sepFilter2D_BitExact(_src, _dst, sdepth,
// ksize,
// (const uint32_t*)&fkx[0], (const uint32_t*)&fky[0],
// Point(-1, -1), 0, borderType,
// 16/*shift_bits*/)
// );
Mat src = _src.getMat();
Mat dst = _dst.getMat();
if (src.data == dst.data)
src = src.clone();
CV_CPU_DISPATCH(GaussianBlurFixedPoint, (src, dst, (const uint32_t*)&fkx[0], (int)fkx.size(), (const uint32_t*)&fky[0], (int)fky.size(), borderType),
CV_CPU_DISPATCH_MODES_ALL);
return;
}
}
#ifdef HAVE_OPENCL
if (useOpenCL)