Memory function of the boost::gil library

六眼飞鱼酱① 提交于 2021-02-08 07:26:22

问题


I am currently trying to make some TensorFlow Inference (C backend) using Boost::GIL (challenging). I need a few thinks, I have been able to load my png image (rgb8_image_t) and did a conversion to rgb32_f_image_t.

I still need 3 thinks, the raw pointer of the data, memory allocated, and dimensions.

  • for the memory allocated unfortunately the function total_allocated_size_in_bytes() is private, so I did this:

    boost::gil::view(dest).size() * boost::gil::view(dest).num_channels() * sizeof(value_type);

Which is valid, if I do not have any extra padding for alignment story. But does it exist any nice alternative?

  • For the dimension, I should match with numpy (from PILLOW), I hope both libraries are using the same memory layout pattern. From my understanding, by default, datas are interleaved and contiguous so, it should be good.

  • Last the raw pointer _memory, it is a private data member of the Image class with no dedicated function. boost::gil::view(dest).row_begin(0) returns a iterator on the first pixel but I not sure how I could get the pointer of the data _memory. Any suggestions ?

Thank you very much,

++t

ps: TensorFlow proposes a C++ backend, however, it is not installed from any package managers, and manipulate Bazel is beyond my strength.


回答1:


GIL documentation pretty accurately documents the various memory layouts.

The point of the library, though, is to abstract away the memory layouts. If you require some representation (planar/interleaved, packed or unpacked) you are doing things "the hard way" for the library interface.

So, I think you can read and convert in one go, e.g. for a jpeg:

gil::rgb32f_image_t img;
gil::image_read_settings<gil::jpeg_tag> settings;
read_and_convert_image("input.jpg", img, settings);

Now getting the raw data is possible:

auto* raw_data = gil::interleaved_view_get_raw_data(view(img));

It happens to be the case that the preferred implementation storage is interleaved, which is likely what you're expecting. If your particular image storage is planar, the call will not compile (and you'd probably want planar_view_get_raw_data(vw, plane_index) instead).

Note that you'll have to reinterpret_cast to float [const]* if you need that, because there is not public interface to get a reference to the scoped_channel_value<>::value_, but the BaseChannelValue type is indeed float and you can assert that the wrapper doesn't add additional weight:

static_assert(sizeof(float) == sizeof(raw_data[0]));

Alternative Approach:

Conversely, you can setup your own raw pixel buffer, mount a mutable view into it and use that to read/convert your initial load into:

// get dimension
gil::image_read_settings<gil::jpeg_tag> settings;
auto info = gil::read_image_info("input.jpg", settings).get_info();

// setup raw pixel buffer & view
using pixel = gil::rgb32f_pixel_t;
auto data = std::make_unique<pixel[]>(info._width * info._height);
auto vw = gil::interleaved_view(info._width, info._height, data.get(),
                                info._width * sizeof(pixel));

// load into buffer
read_and_convert_view("input.jpg", vw, settings);

I've actually checked that it works correctly by writing out the resulting view:

//// just for test - doesn't work for 32f, so choose another pixel format
//gil::write_view("output.png", vw, gil::png_tag());


来源:https://stackoverflow.com/questions/61360466/memory-function-of-the-boostgil-library

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!