/******************************************************* * Copyright (c) 2014, ArrayFire * All rights reserved. * * This file is distributed under 3-clause BSD license. * The complete license agreement can be obtained at: * http://arrayfire.com/licenses/BSD-3-Clause ********************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include using af::dim4; using detail::arithOp; using detail::Array; using detail::createValueArray; using detail::range; using detail::reduce_all; using detail::scalar; using detail::transpose; using detail::unaryOp; template Array gaussianKernel(const int rows, const int cols, const double sigma_r, const double sigma_c) { const dim4 odims = dim4(rows, cols); double sigma = 0; Array tmp = createValueArray(odims, scalar(0)); Array half = createValueArray(odims, 0.5); Array zero = createValueArray(odims, scalar(0)); if (cols > 1) { Array wt = range(dim4(cols, rows), 0); Array w = transpose(wt, false); Array c = createValueArray( odims, scalar(static_cast(cols - 1) / 2.0)); w = arithOp(w, c, odims); sigma = sigma_c > 0 ? sigma_c : 0.25 * cols; Array sig = createValueArray(odims, sigma); w = arithOp(w, sig, odims); w = arithOp(w, w, odims); tmp = arithOp(w, tmp, odims); } if (rows > 1) { Array w = range(dim4(rows, cols), 0); Array r = createValueArray( odims, scalar(static_cast(rows - 1) / 2.0)); w = arithOp(w, r, odims); sigma = sigma_r > 0 ? sigma_r : 0.25 * rows; Array sig = createValueArray(odims, sigma); w = arithOp(w, sig, odims); w = arithOp(w, w, odims); tmp = arithOp(w, tmp, odims); } tmp = arithOp(half, tmp, odims); tmp = arithOp(zero, tmp, odims); tmp = unaryOp(tmp); // Use this instead of (2 * pi * sig^2); // This ensures the window adds up to 1 T norm_factor = reduce_all(tmp); Array norm = createValueArray(odims, norm_factor); Array res = arithOp(tmp, norm, odims); return res; } af_err af_gaussian_kernel(af_array *out, const int rows, const int cols, const double sigma_r, const double sigma_c) { try { af_array res; res = getHandle( gaussianKernel(rows, cols, sigma_r, sigma_c)); std::swap(*out, res); } CATCHALL; return AF_SUCCESS; }