tensorflow — создает входной тензор из буфера gstreamer

В настоящее время я пишу плагин Gstreamer1.0, который будет перехватывать кадр, использовать тензорный поток для выполнения некоторой задачи, записывать данные в кадр и вставлять их обратно.

Я делаю это на C/C++, и в настоящее время я сталкиваюсь с проблемой, когда данные должны передаваться между Gstreamer и Tensorflow.

У меня есть кадр в объекте GstBuffer, из которого я должен извлечь данные и создать входной тензор. Формат всегда один и тот же, матрица UINT8 RGB [ширина, высота, 3].

/* extract raw data from gstreamer buffer */
gpointer bytes;
gst_buffer_extract_dup(outbuf, 0, size, &bytes, &copied);

Теперь с указателем байтов мне нужно построить:

Tensor input(tensorflow::DT_UINT8, tensorflow::TensorShape(cwidth, cheight, 3));

Я понятия не имею, как я должен это сделать.
Я не смог найти никакой информации или примера о том, как я могу работать с gpointer, а в тензорном потоке я мог найти только примеры, использующие файл в качестве источника, который не является моим дело вообще.

Мы будем очень признательны за любые выводы или идеи.


person god_kane    schedule 12.12.2017    source источник


Ответы (2)


Я нашел способ, но он работает только тогда, когда ваш буфер представляет собой трехканальный буфер кадра RGB.

Tensor ConvertRGBBufferToInputTensor(gpointer buffer, gint cwidth, gint cheight, gint channel) {

    Tensor input_tensor(tensorflow::DT_UINT8, tensorflow::TensorShape({1, cwidth, cheight, channel}));
    auto input_tensor_mapped = input_tensor.tensor<uint8_t, 4>();

    uint8_t * uintdata = (uint8_t*)buffer;

    for (int y = 0; y < cheight; ++y) {
        const uint8_t* source_row = uintdata + (y * cwidth * channel);
        for (int x = 0; x < cwidth; ++x) {
            const uint8_t* source_pixel = source_row + (x * channel);
            for (int c = 0; c < channel; ++c) {
                const uint8_t* source_value = source_pixel + c;
                input_tensor_mapped(0, y, x, c) = *source_value;
            }
        }
    }

    return input_tensor;
}

И использовать его из gstreamer, когда у вас есть GstBuffer

/* extract raw data from the buffer and convert it to an input tensor */
gst_buffer_extract_dup(outbuf, 0, size, &bytes, &copied);
GST_INFO("Extracted %" G_GSIZE_FORMAT " from buffer" , copied);
Tensor input_tensor = ConvertRGBBufferToInputTensor(bytes, cwidth, cheight);
g_free(bytes);
person god_kane    schedule 18.12.2017

Он уже реализован и развернут для разработчиков приложений gstreamer: https://github.com/nnsuite/nnstreamer.

Вы можете написать конвейеры GStreamer, такие как,

camsrc ! videoconvert ! videorate ! videoscale ! video/x-raw, whatever-format-you-need ! tensor_converter ! tensor_filter framework=tensorflow model=your-own-model-file.pb ! ....

Если вам нужно транспонировать

camsrc ! videoconvert ! videorate ! videoscale ! video/x-raw, whatever-format-you-need ! tensor_converter ! tensor_transform mode=transpose option=1:2:0:3 ! tensor_filter framework=tensorflow model=your-own-model-file.pb ! ....

Если вы хотите импортировать результаты в свое приложение, вы можете добавить app_sink или tensor_sink и получить там полученные тензоры.

person MZX    schedule 13.12.2019