From 44ec2e7c1edd57eb2fb2674a28452aac02bd8c0a Mon Sep 17 00:00:00 2001 From: Gian Marco Date: Thu, 19 Oct 2017 14:13:38 +0100 Subject: COMPMID-639 - Add PPMAccessor and TopNPredictionsAccessor in graph_utils Change-Id: I40c3e2dfcde10c65ed9c86f9283a53f9e679d4fa Reviewed-on: http://mpd-gerrit.cambridge.arm.com/92437 Reviewed-by: Anthony Barbier Tested-by: Kaizen --- utils/Utils.h | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) (limited to 'utils/Utils.h') diff --git a/utils/Utils.h b/utils/Utils.h index b0e1abeb5f..c88de0e16b 100644 --- a/utils/Utils.h +++ b/utils/Utils.h @@ -263,6 +263,88 @@ public: } } + /** Fill a tensor with 3 planes (one for each channel) with the content of the currently open PPM file. + * + * @note If the image is a CLImage, the function maps and unmaps the image + * + * @param[in,out] tensor Tensor with 3 planes to fill (Must be allocated, and of matching dimensions with the opened PPM). Data types supported: U8/F32 + * @param[in] bgr (Optional) Fill the first plane with blue channel (default = false) + */ + template + void fill_planar_tensor(T &tensor, bool bgr = false) + { + ARM_COMPUTE_ERROR_ON(!is_open()); + ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&tensor, 1, DataType::U8, DataType::F32); + ARM_COMPUTE_ERROR_ON(tensor.info()->dimension(0) != _width || tensor.info()->dimension(1) != _height || tensor.info()->dimension(2) != 3); + + try + { + // Map buffer if creating a CLTensor + map(tensor, true); + + // Check if the file is large enough to fill the image + const size_t current_position = _fs.tellg(); + _fs.seekg(0, std::ios_base::end); + const size_t end_position = _fs.tellg(); + _fs.seekg(current_position, std::ios_base::beg); + + ARM_COMPUTE_ERROR_ON_MSG((end_position - current_position) < tensor.info()->tensor_shape().total_size(), + "Not enough data in file"); + ARM_COMPUTE_UNUSED(end_position); + + // Iterate through every pixel of the image + arm_compute::Window window; + window.set(arm_compute::Window::DimX, arm_compute::Window::Dimension(0, _width, 1)); + window.set(arm_compute::Window::DimY, arm_compute::Window::Dimension(0, _height, 1)); + window.set(arm_compute::Window::DimZ, arm_compute::Window::Dimension(0, 1, 1)); + + arm_compute::Iterator out(&tensor, window); + + unsigned char red = 0; + unsigned char green = 0; + unsigned char blue = 0; + + size_t stride_z = tensor.info()->strides_in_bytes()[2]; + + arm_compute::execute_window_loop(window, [&](const arm_compute::Coordinates & id) + { + red = _fs.get(); + green = _fs.get(); + blue = _fs.get(); + + switch(tensor.info()->data_type()) + { + case arm_compute::DataType::U8: + { + *(out.ptr() + 0 * stride_z) = bgr ? blue : red; + *(out.ptr() + 1 * stride_z) = green; + *(out.ptr() + 2 * stride_z) = bgr ? red : blue; + break; + } + case arm_compute::DataType::F32: + { + *reinterpret_cast(out.ptr() + 0 * stride_z) = static_cast(bgr ? blue : red); + *reinterpret_cast(out.ptr() + 1 * stride_z) = static_cast(green); + *reinterpret_cast(out.ptr() + 2 * stride_z) = static_cast(bgr ? red : blue); + break; + } + default: + { + ARM_COMPUTE_ERROR("Unsupported data type"); + } + } + }, + out); + + // Unmap buffer if creating a CLTensor + unmap(tensor); + } + catch(const std::ifstream::failure &e) + { + ARM_COMPUTE_ERROR("Loading PPM file: %s", e.what()); + } + } + private: std::ifstream _fs; unsigned int _width, _height; -- cgit v1.2.1