Как использовать цвет LUT в Qt QImage - PullRequest
1 голос
/ 31 марта 2011

У меня есть какой-то устаревший код, который записывал в файл NITF для отображения некоторых изображений. В унаследованном коде это выглядит так, как если бы использовалась LUT, и был фрагмент кода, который записывал строку в файл NITF за раз, и значения этой строки вычислялись так:

// convert RGB to LUT values
unsigned char *lutData = new unsigned char[numBytes/3];
for (unsigned j = 0 ; j < numBytes/3 ; j++)
    lutData[j] = (unsigned char) stuff;

Где данные были моим исходным массивом беззнаковых символов.

Так что теперь я пытаюсь взять этот массив данных и вывести его в QImage в моем графическом интерфейсе.

Мне показалось, что в NITF был блок данных LUT, размер которого был "row x cols", верно? Поэтому я создал массив этих данных:

unsigned char *lutData = new unsigned char[imwidth * imheight];
QImage *qi = new QImage(imwidth,imheight, QImage::Format_Indexed8);
for (int i = 0 ; i < imheight ; i++)
{
             #pragma omp parallel for
              for (int j = 0 ; j < imwidth ; j++)
              {
                     lutData[i*imwidth + j] = stuff;
              }
}

и затем я попытался заполнить изображение следующим образом:

   for (int i = 0 ; i < imheight ; i++)
   {
                #pragma omp parallel for
                 for (int j = 0 ; j < imwidth ; j++)
                 {
                     qi->setPixel(j,i,qRgb(lutData[i*imwidth + j],lutData[i*imwidth + j],lutData[i*imwidth + j]));
                }
   }

Однако, похоже, это более или менее просто дает мне изображение в градациях серого вместо моих фактических данных.

Что я делаю не так?

Спасибо!

Ответы [ 2 ]

2 голосов
/ 31 марта 2011

Конструктор qRgb выглядит следующим образом:

qRgb(int r, int g, int b)

Вы передаете одинаковое значение (lutData[i*imwidth + j]) для всех трех цветов, так что в итоге вы получите изображение в оттенках серого.

Теперь qRgb - это просто typedef ed unsigned int, поэтому, если вы храните свои цвета в этом формате (RGB32 / ARGB32), вы можете просто позвонить:

qi->setPixel(j, i, lutData[i*imwidth + j])

Но вы можете захотеть использовать встроенную в QImage поддержку поиска таблицы (она же таблица цветов) - это может закончиться так просто:

QImage image(data, imwidth, imheight, QImage::Format_Indexed8);
QVector<QRgb> colorTable;
// Translate each color in lutData to a QRgb and push it onto colorTable;
image.setColorTable(colorTable);

Надеюсь, этоhelp!

Обновление: Для справки вот тестовый код, который я использовал, чтобы опробовать QImage в режиме индексированного цвета (компилируется без предупреждений с помощью g ++ - просто не забудьте связать с -lQtCore и -lQtGui):

#include <QtCore/QVector>
#include <QtGui/QApplication>
#include <QtGui/QImage>
#include <QtGui/QLabel>
#include <QtGui/QPixmap>

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);

    unsigned char indices[1024];
    for(int i = 0; i < 1024; ++i)
    {
        indices[i] = qrand() & 0x0f;
    }

    QVector<QRgb> ctable;
    for(int i = 0; i < 16; ++i)
    {
        ctable.append(qRgb(qrand() & 0xff, qrand() & 0xff, qrand() & 0xff));
    }

    QImage image(indices, 32, 32, QImage::Format_Indexed8);
    image.setColorTable(ctable);

    QLabel label;
    label.setPixmap(QPixmap::fromImage(image));
    label.show();

    return app.exec();
} 
0 голосов
/ 01 апреля 2011

Очень интересное сжатие изображений.Вот моя попытка преобразовать изображение RGB888 в Index8 с помощью вашей функции:

    QImage image8(image.size(), QImage::Format_Indexed8);
    QVector<QRgb> lut(256);
    for(int i=0;i<image888.height();++i) {
        const uchar * p = image888.bits() + image888.bytesPerLine()*i;
        uchar * q = image8.bits() + image8.bytesPerLine()*i;
        for(int j=0;j<image.width();++j, p+=3) {
            QRgb c = qRgb(p[0], p[1], p[2]);
            int n = qRed(c)/51*36 + qGreen(c)/51*6+qBlue(c)/51;
            lut[n] = c;
            *q++ = n;
        }
    }
    image8.setColorTable(lut);

По сути, он заполняет 8-битную таблицу цветов при преобразовании из 888 в 8-битные данные.Для лучшего результата вы можете накапливать значения RGB по индексу, а затем усреднять значения перед тем, как поместить их в таблицу цветов.Он также может использовать некоторую оптимизацию при обходе буфера изображения.

...