Russian Qt Forum
Ноябрь 02, 2024, 00:25 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Оптимизация конвертации  (Прочитано 3492 раз)
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« : Октябрь 11, 2011, 10:20 »

Как можно оптимизировать следующий код ?

Код:
QImage *ResizePreview::nv21torgb(CameraFrame *frame) {

    QByteArray *data = frame->data;
    int width = frame->width;
    int height = frame->height;

    QImage *img = new QImage(width,height,QImage::Format_ARGB32);


    int frameSize = width * height;

    int uvp = 0;
    int u = 0;
    int v = 0;
    int y = 0;
    int r = 0;
    int g = 0;
    int b = 0;

       for (int j = 0, yp = 0; j < height; ++j) {
           uvp = frameSize + (j >> 1) * width;
           u = 0;
           v = 0;

           for (int i = 0; i < width; ++i, ++yp) {
               y = (0xff & (int)data->at(yp));

               if ((i & 1) == 0) {
                   v = (0xff & ((int)data->at(uvp++)) - 128;
                   u = (0xff & ((int)data->at(uvp++)) - 128;
               }

               r = y + 1.402f * v;
               g = y - 0.34414f * u - 0.71414f * v;
               b = y + 1.772f * u;

               if (r < 0) r = 0; else if (r > 255) r = 255;
               if (g < 0) g = 0; else if (g > 255) g = 255;
               if (b < 0) b = 0; else if (b > 255) b = 255;

               img->setPixel(i,j,qRgba(r,g,b,255));
           }
       }

   return img;
}

этот код конвертирует изображения из nv21 в rgb и работает не сильно шустро 4 - 7 раз в секунду, хотелось бы оптимизировать до 12 -14. что здесь можно изменить?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Октябрь 11, 2011, 12:40 »

1) Ну конечно работать с пикселями напрямую вместо setPixel. Учитывая что число байт в строке может быть больше числа пикселей * размер пикселя, надо использовать scanLine. Полагается что выходной имедж 32 бита на пиксель (ну может 24). Для остальных (редко используемых) - то что сейчас

2) Объявление int r, g, b ощутимо снижает качество, а скорость сильно не поднимает. Лучше считать все во float, а также добавить бухгалтерское округление

Edit: at тоже (возможно) что-то отгрызает, лучше взять (const char *) - стоить проверить.
« Последнее редактирование: Октябрь 11, 2011, 12:52 от Igors » Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #2 : Октябрь 11, 2011, 14:25 »

насчет r,g,b уже пробовал разницу почти не заметил, тоже с const char*. А вот как работать с пикселями напрямую ? я то думал что setPixel - это напрямую Улыбающийся
Записан
BRE
Гость
« Ответ #3 : Октябрь 11, 2011, 15:41 »

насчет r,g,b уже пробовал разницу почти не заметил, тоже с const char*. А вот как работать с пикселями напрямую ? я то думал что setPixel - это напрямую Улыбающийся
Картинка храниться в одном непрерывном куске памяти как последовательность точек, строка за строкой, начиная с верхней, слева направо.
Ты задал формат QImage::Format_ARGB32, значит каждая точка будет состоять из 4 байт в порядке: Alpha, Red, Green, Blue.
Начало этого возвращает метод:
uchar * QImage::bits ()

Метод setPixel каждый раз будет вычислять позицию в буфере, а вместо этого можно двигаться по этому буферу последовательно и не чего не вычислять. Подмигивающий
« Последнее редактирование: Октябрь 11, 2011, 16:43 от BRE » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Октябрь 11, 2011, 17:19 »

Код:
       for (int j = 0, yp = 0; j < height; ++j) {
           uvp = frameSize + (j >> 1) * width;
В последующем цикле не увидел какая еще разница между j = 0 и j = 1 (кроме записи выходных пикселей). Так может сделать цикл j +=2 и писать по 2 пикселя  

Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.105 секунд. Запросов: 22.