Функция памяти библиотеки boost :: gil - PullRequest
1 голос
/ 22 апреля 2020

В настоящее время я пытаюсь сделать вывод TensorFlow (C backend), используя Boost::GIL (сложный). Мне нужно несколько мыслей, я смог загрузить свое изображение png (rgb8_image_t) и сделал преобразование в rgb32_f_image_t.

Мне все еще нужно 3 мысли, необработанный указатель данных, выделенная память и размеры.

  • для памяти, выделенной, к сожалению, функция total_allocated_size_in_bytes() является закрытой, поэтому я сделал это:

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

Что действительно, если у меня нет дополнительных отступов для истории выравнивания. Но существует ли какая-нибудь хорошая альтернатива?

  • Для измерения я должен соответствовать numpy (из PILLOW), я надеюсь, что обе библиотеки используют один и тот же шаблон макета памяти. Насколько я понимаю, по умолчанию данные чередуются и являются смежными, поэтому это должно быть хорошо.

  • Последний необработанный указатель _memory, это частный элемент данных Image класс без выделенной функции. boost::gil::view(dest).row_begin(0) возвращает итератор для первого пикселя, но я не уверен, как получить указатель на данные _memory. Любые предложения?

Большое спасибо,

++ t

ps: TensorFlow предлагает бэкэнд C ++, однако он не устанавливается из любые менеджеры пакетов и манипулирование с Базелем не в моих силах.

1 Ответ

1 голос
/ 27 апреля 2020

Документация GIL довольно точно документирует различные макеты памяти.

Однако цель библиотеки - абстрагировать макеты памяти. Если вам требуется некоторое представление (плоское / чередованное, упакованное или распакованное), вы делаете вещи "сложным образом" для интерфейса библиотеки.

Итак, я думаю, что вы можете читать и конвертировать в один go, например, для jpeg:

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

Теперь получение необработанных данных возможно:

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

Это тот случай, когда предпочтительная реализация хранилища чередуется, что вполне вероятно, что вы ожидаете. Если ваше конкретное хранилище изображений является плоским, вызов не будет скомпилирован (и вы, вероятно, захотите вместо него planar_view_get_raw_data(vw, plane_index)).

Обратите внимание, что вам придется повторно интерпретировать_cast для float [const]*, если вам нужно это потому, что нет интерфейса publi c для получения ссылки на scoped_channel_value<>::value_, но тип BaseChannelValue действительно float, и вы можете утверждать, что оболочка не добавляет дополнительный вес:

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

Альтернативный подход:

И наоборот, вы можете настроить свой собственный буфер необработанных пикселей, смонтировать в него изменяемый вид и использовать его для чтения / преобразования вашей начальной загрузки в:

// 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);

Я на самом деле проверил, что он работает правильно, выписав получившийся вид:

//// just for test - doesn't work for 32f, so choose another pixel format
//gil::write_view("output.png", vw, gil::png_tag());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...