C ++: функция с буфером и указателем l oop - возможности для оптимизации? - PullRequest
1 голос
/ 21 апреля 2020

Я написал функцию для преобразования изображения с двумя байтами в 8-битное изображение, взяв только верхние байты.

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

Эта функция вызывается для обработки каждого кадра видеопотока.

Знаете ли вы возможности оптимизировать функцию по скорости?

Спасибо!

QImage* createQImage(uchar *ptr, uint width, uint height, uint channels)
{
   static uint size = width * height * channels;
   static uchar *buffer = new uchar[size];


   //Take every second byte (upper byte)
   for(uint i=0; i<size; i++) {
       buffer[i] = (*(ptr+1));
       ptr = ptr+2;
   }

   static QImage img = QImage(buffer, width, height, QImage::Format_BGR888);
   static QImage *ptr_img = &img;

   return ptr_img;
}

1 Ответ

0 голосов
/ 21 апреля 2020

Если вы просто перемещаете входной буфер в выходной буфер, делать это по одному байту за раз - не самый быстрый. Просто приведите uchar *ptr к uint64_t* и вытяните байты с помощью битовых сдвигов / масок, возможно, это способ оптимизировать это. В итоге у вас останется несколько байтов, которые вам нужно будет обработать «вручную», так же, как вы уже это делаете. Предполагая, что ваши образы 16-битные, а не 16/64 == 4, что дает вам повышение скорости в 4 раза.

Это предполагает, что ваше оборудование может загружать 64 бита за раз, вы можете сделать этот код загруженным 32. биты за раз, используя вместо этого uint32_t, но вполне справедливо предположить, что большинство людей имеют 64-битное оборудование. Код предполагает, что вы используете оборудование с прямым порядком байтов.

Код (не проверен).

QImage* createQImage(uchar* ptr, uint width, uint height, uint channels) {
    uint64_t* nptr = (uint64_t*)ptr;

    static uint size = width * height * channels;
    static uchar *buffer = new uchar[size];
    static uint bytesize = size*2;

    uint idx = 0;
    uint i = 0;
    for(; i + sizeof(uint64_t) <= bytesize; i+=sizeof(uint64_t)) {
        //get 64 bits at a time
        uint64_t val = nptr[i/sizeof(uint64_t)];

        //get 4 bytes at a time
        //note inverted due to little endian assumed (maybe wrong)
        buffer[idx] = (uchar)(val >> (8 * 6));
        ++idx;
        buffer[idx] = (uchar)(val >> (8 * 4));
        ++idx;
        buffer[idx] = (uchar)(val >> (8 * 2));
        ++idx;
        buffer[idx] = (uchar)(val >> (8 * 0));
        ++idx;
    }

    //We have some bytes left at the end, process these a byte at a time
    //Take every second byte (upper byte)
    for(; i < bytesize; i+=2) {
        buffer[idx] = (*(ptr + i + 1));
        ++idx;
    }

    static QImage img = QImage(buffer, width, height, QImage::Format_BGR888);
    static QImage *ptr_img = &img;

    return ptr_img;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...