Nano Hash - криптовалюты, майнинг, программирование

Как использовать цветовую LUT в Qt QImage

У меня есть устаревший код, который записывался в файл 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 размером "строки x столбцы", да? Итак, я создал массив этих данных lut:

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;
              }
}

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

   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]));
                }
   }

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

Что я делаю неправильно?

Спасибо!


Ответы:


1

Конструктор qRgb выглядит так:

qRgb(int r, int g, int b)

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

Теперь qRgb — это просто typedefed 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);

Надеюсь это поможет!

Обновление: Для справки, вот тестовый код, который я использовал, чтобы опробовать 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();
} 
31.03.2011
  • Попробовав первый способ, я получил изображение, которое выглядело действительно голубым. Не совсем уверен, почему - я думаю, потому что он имеет наименьший знаменатель в расчете LUT? Но это то, что у них есть в исходном коде - и я могу нормально просматривать выходные данные в ENVI и других программах. 31.03.2011
  • @Derek - Знаете, еще раз взглянув на исходный код, я не думаю, что это таблица поиска. Я думаю, что это процедура сжатия — она берет три байта из data и сжимает их до одного байта в lutData. И размер lutData напрямую связан (x 1/3) с размером data; если бы это была таблица цветов, она не зависела бы от количества пикселей и вместо этого зависела бы от количества цветов ... В каком формате изначально был data? Можете ли вы просто использовать исходный массив data с QImage::Format_RGB888? 01.04.2011
  • данные изначально представляют собой беззнаковый символ *. Это размер imwidth * 3 * imheight, основанный на коде, показанном в моем фрагменте. 01.04.2011
  • @Derek - звучит как хороший кандидат для данных RGB888. Что произойдет, если вы загрузите его прямо в свой QImage, полностью минуя lutData (есть удобный Конструктор QImage в случае ширины != шага)? 01.04.2011
  • когда я использую исходный массив данных и этот формат RGB888, я получаю что-то похожее на сильно размытую версию вывода. То, как это в моем исходном посте, по крайней мере, выглядит правильно и ясно, просто не имеет правильных цветов. 01.04.2011
  • то же самое касается использования этого удобного конструктора, о котором я не знал... выглядит четким, просто кажется, что цвета в оттенках серого. Правильно ли я предполагаю, что если я использую LUT, в LUT должна быть одна запись для каждого пикселя изображения? 01.04.2011
  • @Derek - Как размыто? Если это просто выглядит более плавным, я готов поспорить, что это просто более точное представление информации в data - деление значения в диапазоне [0, 255] дает вам значение в диапазоне [0, 5], зажимая каждый компоненту цвета на один из шести уровней (это также объясняет умножение на 6^X при построении lutData — это сдвиг влево, но по другому основанию). Так что, если вы видите размытое изображение, возможно, вы просто видите более точное изображение (если, конечно, вы не хотите зажимать...)! 01.04.2011
  • @Дерек - Ага! Кажется, я тоже неправильно понял lutData. Это не таблица цветов — это массив индексов в таблице цветов — по одному на каждый пиксель. Это означает, что фактическая таблица цветов все еще где-то плавает; это не data (полные цвета каждого пикселя) и не lutData (индексирует в указанную таблицу цветов для каждого пикселя), поэтому это должна быть какая-то другая переменная... Если вы можете ее найти, вы можете сделать свой QImage Indexed8 из lutData, построить свой QVector‹QRgb› из вашей переменной таблицы цветов, а затем setColorTable()... Вы получите свое старое изображение с зажимом! 01.04.2011
  • Сложно сказать, что он просто более гладкий — черты на изображении практически неузнаваемы. Если бы я собирался использовать метод setColorTable, а это изображение — Format_Indexed8, мне нужен цикл с 256 значениями Максимум для входа в эту таблицу цветов, верно? Как мне тогда решить, какое значение из таблицы цветов будет использоваться для конкретного пикселя? это то, что вычисляет мой lutData? Если это так, может быть, мне нужно посмотреть исходный код, чтобы увидеть, как там рассчитывался colorTable? 01.04.2011
  • ах - у нас, кажется, был момент ах-ха одновременно.. Я опубликую результаты 01.04.2011
  • Привет. Я создал вектор из 256 элементов QRgb и использовал qi.setColorTable(myVector), чтобы установить его на изображении. Однако мне нужно поместить это в QGraphicsPixmapItem для отображения, но когда я запускаю метод: QPixmap::fromImage(*qi,Qt::AutoColor) я получаю ошибку сегментации - есть идеи? 01.04.2011
  • @Derek - Трудно сказать, не видя твоего кода. Я добавил код, который я использовал для проверки, к своему ответу - вы можете сравнить и посмотреть, есть ли какие-либо очевидные различия... (я никогда не использовал QGraphicsPixmapItem - если вы просто отображаете изображение, проще просто нарисуйте его в QLabel.Однако он все еще нужен в формате QPixmap.). И нет, ничего не показывает — просто куча рандома 32х32. 02.04.2011

  • 2

    Очень интересное сжатие изображений. Вот моя попытка преобразовать изображение 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 по индексу, а затем усреднять значения, прежде чем помещать их в таблицу цветов. Он также может использовать некоторую оптимизацию при обходе буфера изображения.

    01.04.2011
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..