如何在 Qt QImage 中使用颜色 LUT

发布于 2024-10-28 23:04:04 字数 1230 浏览 7 评论 0原文

我有一些遗留代码正在写入 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;

:我原来的无符号字符数组。

所以现在我尝试获取该数据数组并将其输出到 GUI 中的 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]));
                }
   }

但是,这似乎或多或少只是给了我一个灰度图像,而不是我的实际数据。

我做错了什么?

谢谢!

I have some legacy code that was writing to a NITF file to display some images. In the legacy code, it appears as if there was a LUT being used, and there was a section of code that wrote out a row at a time to the NITF file , and the values of that row were calculated like so:

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

Where data was my original array of unsigned chars.

So now I am trying to take that data array and output it into a QImage in my GUI.

It would seem to me in the NITF, there was a block of LUT data that was "rows x cols" in size, right? So I created an array of that lut data:

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

and then I tried to populate the qimage like this:

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

However, this seems to more or less just give me a grayscale image, instead of my actual data.

What am I doing wrong?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

倾其所爱 2024-11-04 23:04:04

qRgb 构造函数如下所示:

qRgb(int r, int g, int b)

您为所有三种颜色传递相同的值 (lutData[i*imwidth + j]),因此您最终会得到一个灰度图像。

现在,qRgb 只是一个 typedefed unsigned int,所以如果您将颜色存储在 format (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();
} 

The qRgb constructor looks like this:

qRgb(int r, int g, int b)

You're passing in the same value (lutData[i*imwidth + j]) for all three colors, so you'll end up with a greyscale image.

Now, qRgb is just a typedefed unsigned int, so if you store your colors in that format (RGB32 / ARGB32), you can just call:

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

But you might want to look into using QImage's built-in lookup table (aka color table) support - it might end up being as simple as:

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

Hope this helps!

Update: For reference purposes, here's the test code I used to try out QImage in indexed color mode (compiles without warnings with g++ - just remember to link to -lQtCore and -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();
} 
尛丟丟 2024-11-04 23:04:04

非常有趣的图像压缩。这是我尝试使用您的函数将 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);

当它从 888 转换为 8 位数据时,它基本上填满了 8 位颜色表。为了获得更好的结果,您可以在索引处累积 RGB 值,然后对这些值进行平均,然后再将它们放入颜色表中。它还可以在遍历图像缓冲区时使用一些优化。

Very interesting image compression. Here's my try to convert a RGB888 image into a Index8 with your function:

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

It basically fills up the 8-bit color table as it converts from 888 to 8-bit data. For better result, you can accumulate the RGB values at an index, then average the values before putting them into the color table. It can also use some optimization on walking the image buffer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文