| 264 | |
| 265 | template<typename InputType, typename RealType = float> |
| 266 | af_array invDeconv(const af_array in, const af_array ker, const float gamma, |
| 267 | const af_inverse_deconv_algo algo) { |
| 268 | using T = RealType; |
| 269 | using CT = typename std::conditional<std::is_same<T, double>::value, |
| 270 | cdouble, cfloat>::type; |
| 271 | auto input = castArray<T>(in); |
| 272 | auto psf = castArray<T>(ker); |
| 273 | const dim4& idims = input.dims(); |
| 274 | const dim4& fdims = psf.dims(); |
| 275 | dim_t nElems = 1; |
| 276 | |
| 277 | dim4 inUPad, psfUPad, inLPad, psfLPad, odims(1); |
| 278 | |
| 279 | auto index = calcPadInfo(inLPad, psfLPad, inUPad, psfUPad, odims, nElems, |
| 280 | idims, fdims); |
| 281 | auto paddedIn = |
| 282 | padArrayBorders<T>(input, inLPad, inUPad, AF_PAD_CLAMP_TO_EDGE); |
| 283 | auto paddedPsf = padArrayBorders<T>(psf, psfLPad, psfUPad, AF_PAD_ZERO); |
| 284 | const array<int, 4> shiftDims = {-int(fdims[0] / 2), -int(fdims[1] / 2), 0, |
| 285 | 0}; |
| 286 | |
| 287 | auto shiftedPsf = shift(paddedPsf, shiftDims.data()); |
| 288 | |
| 289 | auto I = fft_r2c<CT, T>(paddedIn, BASE_DIM); |
| 290 | auto P = fft_r2c<CT, T>(shiftedPsf, BASE_DIM); |
| 291 | auto Pc = conj(P); |
| 292 | auto numer = arithOp<CT, af_mul_t>(I, Pc, I.dims()); |
| 293 | auto denom = denominator(I, P, gamma, algo); |
| 294 | auto absVal = detail::abs<T, CT>(denom); |
| 295 | auto THRESH = createValueArray(I.dims(), scalar<T>(gamma)); |
| 296 | auto cond = logicOp<T, af_ge_t>(absVal, THRESH, absVal.dims()); |
| 297 | auto val = arithOp<CT, af_div_t>(numer, denom, numer.dims()); |
| 298 | |
| 299 | select_scalar<CT, false>(val, cond, val, scalar<CT>(0.0)); |
| 300 | |
| 301 | auto ival = |
| 302 | fft_c2r<CT, T>(val, 1 / static_cast<double>(nElems), odims, BASE_DIM); |
| 303 | |
| 304 | return getHandle(createSubArray<T>(ival, index)); |
| 305 | } |
| 306 | |
| 307 | af_err af_inverse_deconv(af_array* out, const af_array in, const af_array psf, |
| 308 | const float gamma, const af_inverse_deconv_algo algo) { |
nothing calls this directly
no test coverage detected