【问题标题】:How can I colorize my grayscale 16 bit image using Qt?如何使用 Qt 为我的灰度 16 位图像着色?
【发布时间】:2020-05-02 18:42:27
【问题描述】:

我有一个 16 位灰度 QImage::Format_Grayscale16unsigned short 值在内存中是连续的。在将QLabel 转换为像素图后,它会正确显示在QLabel 上。我现在需要使用将强度映射到特定 RGB 值的给定颜色表对其进行着色:

QVector<QRgb> table_16;
for (double i = 0; i < 4096; ++i) {

    table_16.append(qRgb(
        (int)std::round(std::clamp( -4 * std::abs(i - 4095.0 * 3 / 4) + 4095.0 * 3 / 2, 0.0, 4095.0)),
        (int)std::round(std::clamp(-4 * std::abs(i - 4095.0 * 2 / 4) + 4095.0 * 3 / 2, 0.0, 4095.0)),
        (int)std::round(std::clamp( -4 * std::abs(i - 4095.0 * 1 / 4) + 4095.0 * 3 / 2, 0.0, 4095.0))));

}

table_16[0] = qRgb(4095, 4095, 4095);

注意:图像实际上是 12 位的,但存储方式与 16 位图像相同。因此 RGB 映射的限制为 4096。

很遗憾,我遇到了麻烦。首先,转换为 RGB16 格式是否正确?我发布了另一个非常相似的问题,但针对 8 位灰度。 setColorTable() 的 Qt 文档指出:

仅单色和 8 位格式。

所以我假设我不能将它用于我的 16 位图像。最好的做法是缩小并转换为 8 位吗?任何性能优化都会很好,因为图像应该是实时流式传输的。

【问题讨论】:

    标签: qt image-processing qimage image-formats


    【解决方案1】:

    qRgb(int,int,int) 创建一个 QRgb,每个通道存储 8 位(而参数是整数,they are masked against 0xff)。 qRgb64(..) 将接受(并使用)16 位值来创建具有必要精度的QRgb64

    不幸的是,目前还没有QImage::Format_Indexed16(请参阅QTBUG-75536)来解释为什么 Qt 不支持直接使用 16 位灰度的颜色表。如果您不需要低 8 位中的对比度数据(或者在您的情况下仅需要 4 位,因为只有高 12 位具有实际数据)并且颜色表始终相同,则转换为 Format_Indexed8 并使用颜色表将是最直接的方法。

    如果您确实需要较低位的对比度数据,则需要在每通道 8 位 RGB 中手动缩放这 12 位。创建一个具有相同宽度/高度的新QImage,并逐个像素地遍历原始数据。 Gray16Lib 是一个 Qt 库,其中包含各种尝试保持对比度的算法示例(免责声明,我写的)。

    【讨论】:

      【解决方案2】:

      一个稍微昂贵的解决方案如下:

      使用convertToFormat(QImage::Format_Grayscale8) 创建一个新的 8 位图像

      通过创建Indexed8 格式的 QImage、设置其颜色表并将 8 位 QImage 数据复制到这个新的Indexed8 格式图像来着色。有关更多详细信息,请参阅我的另一个问题。

      这可行,但如果有人知道更快的方法,请随时回复。似乎有很多复制。我已经必须遍历图像一次才能将 12 位映射到 16 位范围。

      【讨论】:

        猜你喜欢
        • 2017-07-31
        • 2017-08-07
        • 2011-11-23
        • 2012-05-28
        • 1970-01-01
        • 2015-07-01
        • 2015-08-11
        • 2015-06-29
        相关资源
        最近更新 更多