diff options
author | Anthony Barbier <anthony.barbier@arm.com> | 2017-09-04 18:44:23 +0100 |
---|---|---|
committer | Anthony Barbier <anthony.barbier@arm.com> | 2018-09-17 13:03:09 +0100 |
commit | 6ff3b19ee6120edf015fad8caab2991faa3070af (patch) | |
tree | a7a6dcd16dfd56d79fa1b56a313caeebcc939b68 /src/core/NEON/kernels/NECumulativeDistributionKernel.cpp | |
download | ComputeLibrary-6ff3b19ee6120edf015fad8caab2991faa3070af.tar.gz |
COMPMID-344 Updated doxygen
Change-Id: I32f7b84daa560e460b77216add529c8fa8b327ae
Diffstat (limited to 'src/core/NEON/kernels/NECumulativeDistributionKernel.cpp')
-rw-r--r-- | src/core/NEON/kernels/NECumulativeDistributionKernel.cpp | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/core/NEON/kernels/NECumulativeDistributionKernel.cpp b/src/core/NEON/kernels/NECumulativeDistributionKernel.cpp new file mode 100644 index 0000000000..32789cbe33 --- /dev/null +++ b/src/core/NEON/kernels/NECumulativeDistributionKernel.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2016, 2017 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "arm_compute/core/NEON/kernels/NECumulativeDistributionKernel.h" + +#include "arm_compute/core/Error.h" +#include "arm_compute/core/Helpers.h" +#include "arm_compute/core/IDistribution1D.h" +#include "arm_compute/core/ILut.h" +#include "arm_compute/core/ITensor.h" +#include "arm_compute/core/Types.h" +#include "arm_compute/core/Validate.h" + +#include <algorithm> +#include <cmath> +#include <numeric> + +using namespace arm_compute; + +NECumulativeDistributionKernel::NECumulativeDistributionKernel() + : _input(nullptr), _distribution(nullptr), _cumulative_sum(nullptr), _output(nullptr) +{ +} + +bool NECumulativeDistributionKernel::is_parallelisable() const +{ + return false; +} + +void NECumulativeDistributionKernel::configure(const IImage *input, const IDistribution1D *distribution, IDistribution1D *cumulative_sum, ILut *output) +{ + ARM_COMPUTE_ERROR_ON_NULLPTR(input, distribution, cumulative_sum, output); + ARM_COMPUTE_ERROR_ON_TENSOR_NOT_2D(input); + + set_format_if_unknown(*input->info(), Format::U8); + + ARM_COMPUTE_ERROR_ON(distribution->num_bins() != cumulative_sum->num_bins()); + ARM_COMPUTE_ERROR_ON(distribution->num_bins() != output->num_elements()); + ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::U8); + ARM_COMPUTE_ERROR_ON(input->info()->data_type() != output->type()); + + _input = input; + _distribution = distribution; + _cumulative_sum = cumulative_sum; + _output = output; + + INEKernel::configure(calculate_max_window(*input->info())); +} + +void NECumulativeDistributionKernel::run(const Window &window) +{ + ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this); + ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(INEKernel::window(), window); + ARM_COMPUTE_ERROR_ON(_distribution->buffer() == nullptr); + ARM_COMPUTE_ERROR_ON(_cumulative_sum->buffer() == nullptr); + ARM_COMPUTE_ERROR_ON(_output->buffer() == nullptr); + ARM_COMPUTE_ERROR_ON_MSG(_distribution->num_bins() < 256, "Distribution must have 256 bins"); + + // Calculate the cumulative distribution (summed histogram). + const uint32_t *hist = _distribution->buffer(); + uint32_t *cumulative_sum = _cumulative_sum->buffer(); + uint8_t *output = _output->buffer(); + + // Calculate cumulative distribution + std::partial_sum(hist, hist + _histogram_size, cumulative_sum); + + // Get the number of pixels that have the lowest value in the input image + const uint32_t cd_min = *std::find_if(hist, hist + _histogram_size, [](const uint32_t &v) + { + return v > 0; + }); + const uint32_t image_size = cumulative_sum[_histogram_size - 1]; + + ARM_COMPUTE_ERROR_ON(cd_min > image_size); + + // Create mapping lookup table + if(image_size == cd_min) + { + std::iota(output, output + _histogram_size, 0); + } + else + { + const float diff = image_size - cd_min; + + for(unsigned int x = 0; x < _histogram_size; ++x) + { + output[x] = lround((cumulative_sum[x] - cd_min) / diff * 255.0f); + } + } +} |