[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/arrayfire/arrayfire/master/test/anisotropic_diffusion.cpp [Back]  [Original]

/*******************************************************
 * Copyright (c) 2017, 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 

using af::array;
using af::exception;
using af::fluxFunction;
using af::max;
using af::min;
using af::randu;
using std::abs;
using std::string;
using std::vector;

template
class AnisotropicDiffusion : public ::testing::Test {};

typedef ::testing::Types
    TestTypes;

TYPED_TEST_SUITE(AnisotropicDiffusion, TestTypes);

template
array normalize(const array &p_in) {
    T mx = max(p_in);
    T mn = min(p_in);
    return (p_in - mn) / (mx - mn);
}

template
void imageTest(string pTestFile, const float dt, const float K,
               const uint iters, fluxFunction fluxKind,
               bool isCurvatureDiffusion = false) {
    typedef
        typename cond_type::type
            OutType;

    SUPPORTED_TYPE_CHECK(T);
    IMAGEIO_ENABLED_CHECK();

    using af::dim4;

    vector inDims;
    vector inFiles;
    vector outSizes;
    vector outFiles;

    readImageTests(pTestFile, inDims, inFiles, outSizes, outFiles);

    size_t testCount = inDims.size();

    for (size_t testId = 0; testId < testCount; ++testId) {
        if (isCurvatureDiffusion) {
            inFiles[testId].insert(0, string(TEST_DIR "/curvature_diffusion/"));
            outFiles[testId].insert(0,
                                    string(TEST_DIR "/curvature_diffusion/"));
        } else {
            inFiles[testId].insert(0, string(TEST_DIR "/gradient_diffusion/"));
            outFiles[testId].insert(0, string(TEST_DIR "/gradient_diffusion/"));
        }

        af_array _inArray   = 0;
        af_array inArray    = 0;
        af_array _outArray  = 0;
        af_array cstArray   = 0;
        af_array minArray   = 0;
        af_array numArray   = 0;
        af_array denArray   = 0;
        af_array divArray   = 0;
        af_array outArray   = 0;
        af_array goldArray  = 0;
        af_array _goldArray = 0;
        dim_t nElems        = 0;

        ASSERT_SUCCESS(
            af_load_image(&_inArray, inFiles[testId].c_str(), isColor));
        ASSERT_SUCCESS(conv_image(&inArray, _inArray));

        ASSERT_SUCCESS(
            af_load_image(&_goldArray, outFiles[testId].c_str(), isColor));
        // af_load_image always returns float array, so convert to output type
        ASSERT_SUCCESS(conv_image(&goldArray, _goldArray));
        ASSERT_SUCCESS(af_get_elements(&nElems, goldArray));

        if (isCurvatureDiffusion) {
            ASSERT_SUCCESS(af_anisotropic_diffusion(&_outArray, inArray, dt, K,
                                                                iters, fluxKind,
                                                                AF_DIFFUSION_MCDE));
        } else {
            ASSERT_SUCCESS(af_anisotropic_diffusion(&_outArray, inArray, dt, K,
                                                                iters, fluxKind,
                                                                AF_DIFFUSION_GRAD));
        }

        double maxima, minima, imag;
        ASSERT_SUCCESS(af_min_all(&minima, &imag, _outArray));
        ASSERT_SUCCESS(af_max_all(&maxima, &imag, _outArray));

        unsigned ndims;
        dim_t dims[4];
        ASSERT_SUCCESS(af_get_numdims(&ndims, _outArray));
        ASSERT_SUCCESS(
            af_get_dims(dims, dims + 1, dims + 2, dims + 3, _outArray));

        af_dtype otype = (af_dtype)af::dtype_traits::af_type;
        ASSERT_SUCCESS(af_constant(&cstArray, 255.0, ndims, dims, otype));
        ASSERT_SUCCESS(
            af_constant(&denArray, (maxima - minima), ndims, dims, otype));
        ASSERT_SUCCESS(af_constant(&minArray, minima, ndims, dims, otype));
        ASSERT_SUCCESS(af_sub(&numArray, _outArray, minArray, false));
        ASSERT_SUCCESS(af_div(&divArray, numArray, denArray, false));
        ASSERT_SUCCESS(af_mul(&outArray, divArray, cstArray, false));

        ASSERT_IMAGES_NEAR(goldArray, outArray, 0.025);

        ASSERT_SUCCESS(af_release_array(_inArray));
        ASSERT_SUCCESS(af_release_array(_outArray));
        ASSERT_SUCCESS(af_release_array(inArray));
        ASSERT_SUCCESS(af_release_array(cstArray));
        ASSERT_SUCCESS(af_release_array(minArray));
        ASSERT_SUCCESS(af_release_array(denArray));
        ASSERT_SUCCESS(af_release_array(numArray));
        ASSERT_SUCCESS(af_release_array(divArray));
        ASSERT_SUCCESS(af_release_array(outArray));
        ASSERT_SUCCESS(af_release_array(_goldArray));
        ASSERT_SUCCESS(af_release_array(goldArray));
    }
}

TYPED_TEST(AnisotropicDiffusion, GradientGrayscale) {
    UNSUPPORTED_BACKEND(AF_BACKEND_ONEAPI);
    // Numeric values separated by underscore are arguments to fn being tested.
    // Divide first value by 1000 to get time step `dt`
    // Divide second value by 100 to get time step `K`
    // Divide third value stays as it is since it is iteration count
    // Fourth value is a 4-character string indicating the flux kind
    imageTest(
        string(TEST_DIR "/gradient_diffusion/gray_00125_100_2_exp.test"),
        0.125f, 1.0, 2, AF_FLUX_EXPONENTIAL);
}

TYPED_TEST(AnisotropicDiffusion, GradientColorImage) {
    UNSUPPORTED_BACKEND(AF_BACKEND_ONEAPI);
    imageTest(
        string(TEST_DIR "/gradient_diffusion/color_00125_100_2_exp.test"),
        0.125f, 1.0, 2, AF_FLUX_EXPONENTIAL);
}

TEST(AnisotropicDiffusion, GradientInvalidInputArray) {
    try {
        array out = anisotropicDiffusion(randu(100), 0.125f, 0.2f, 10,
                                         AF_FLUX_QUADRATIC);
    } catch (exception &exp) { ASSERT_EQ(AF_ERR_SIZE, exp.err()); }
}

TYPED_TEST(AnisotropicDiffusion, CurvatureGrayscale) {
    UNSUPPORTED_BACKEND(AF_BACKEND_ONEAPI);
    // Numeric values separated by underscore are arguments to fn being tested.
    // Divide first value by 1000 to get time step `dt`
    // Divide second value by 100 to get time step `K`
    // Divide third value stays as it is since it is iteration count
    // Fourth value is a 4-character string indicating the flux kind
    imageTest(
        string(TEST_DIR "/curvature_diffusion/gray_00125_100_2_mcde.test"),
        0.125f, 1.0, 2, AF_FLUX_EXPONENTIAL, true);
}

TYPED_TEST(AnisotropicDiffusion, CurvatureColorImage) {
    UNSUPPORTED_BACKEND(AF_BACKEND_ONEAPI);
    imageTest(
        string(TEST_DIR "/curvature_diffusion/color_00125_100_2_mcde.test"),
        0.125f, 1.0, 2, AF_FLUX_EXPONENTIAL, true);
}

TEST(AnisotropicDiffusion, CurvatureInvalidInputArray) {
    try {
        array out = anisotropicDiffusion(randu(100), 0.125f, 0.2f, 10);
    } catch (exception &exp) { ASSERT_EQ(AF_ERR_SIZE, exp.err()); }
}

Web Proxy Viewer  |  New URL  |  Original Page