灰度图像的颜色表

Posted

技术标签:

【中文标题】灰度图像的颜色表【英文标题】:Color tables of grayscale images 【发布时间】:2016-08-05 22:31:02 【问题描述】:

我在 PyQt 中有一个灰度图像,想要获取特定像素的颜色。灰度图像使用包含最多 256 个条目的颜色表。

from PyQt4 import QtGui

def test():
    image = QtGui.QImage(100, 100, QtGui.QImage.Format_Indexed8)
    image.load("d:/1.bmp")
    print image.pixel(1, 1)
    print image.pixelIndex(1, 1)

    image.setColorTable(list([i] for i in range(256)))
    print image.colorTable()

import sys
app = QtGui.QApplication(sys.argv)
window = test()
sys.exit(app.exec_())

这是 d:/1.bmp:

我有以下问题:

image.colorTable() 返回数字 4294967295L(即 2^32-1)的 256 倍的列表,尽管我刚刚将颜色表设置为 0 到 255。

image.pixelIndex(1, 1) 给出消息“QImage::pixelIndex: 不适用于 32-bpp 图像(无调色板)”,尽管格式设置为 Indexed8(并且 isGrayscale() 返回 true)。

image.pixel(1, 1) 返回 4278190080(当我将格式设置为 Format_RGB32 时也是如此)。这是什么颜色? (应该是黑色的。)

根据 ekhumoro 的答案的新代码:

from PyQt4 import QtGui

def test():
    image = QtGui.QImage(100, 100, QtGui.QImage.Format_Indexed8)
    image.load("d:/1.bmp")
    image2 = image.convertToFormat(QtGui.QImage.Format_Indexed8)
    print "format:", image2.format()
    print "pixel color:", QtGui.qGray(image2.pixel(1, 1))

    image2.setColorTable(list([QtGui.qRgb(i, i, i)] for i in range(256)))
    print "color table:", image2.colorTable()

import sys
app = QtGui.QApplication(sys.argv)
window = test()
sys.exit(app.exec_())

【问题讨论】:

【参考方案1】:

docs for QImage 为您解答所有问题:

来自setColorTable()的条目:

设置用于将颜色索引转换为 QRgb 值的颜色表,以指定颜色。使用图像时,颜色表必须足够大,以包含图像中存在的所有像素/索引值的条目,否则结果未定义

来自load()的条目:

加载器尝试使用指定格式读取图像,例如 PNG 或 JPG。 如果未指定格式(这是默认值),加载程序会探测文件以查找文件头以猜测文件格式

因此,您传递给 QImage 构造函数的格式无关紧要,我预测 print image.format() 将输出 > 3 的值。另外,查看 pixelIndex() 的条目我看到了:

如果位置无效,或如果图像不是调色板图像(depth() > 8),则结果未定义

来自pixel()的条目:

QRgb QImage::pixel(int x, int y) 常量。

所以这个函数返回一个 QRgb 类型的值,文档是这样描述的:

#AARRGGBB 格式的 ARGB 四元组,等效于无符号整数。

方便地,Qt 提供了一些函数来提取QRgb 值的各个组成部分。其中之一是qGray,它是这样描述的:

从给定的 ARGB 四元组 rgb 返回一个灰度值(0 到 255)。

(注意:这些函数位于全局命名空间中,因此在 PyQt 中,您会在 QtGui 模块中找到它们。

【讨论】:

好的,我明白index的返回值了。我将image.pixel(1, 1) 替换为QtGui.qGray(image.pixel(1, 1))。对于关于您的答案的颜色表,我认为image.setColorTable(list([QtGui.qRgb(i, i, i)] for i in range(256))) 会创建一个合适的颜色表(包含所有可能的灰度值),但image.colorTable() 仍然返回未定义的值。而且我不明白颜色表与加载图像的格式有什么关系:加载中的格式是指jpg、bmp、png等,我认为它们与单色、8位或32位无关。跨度> 关于image.format:确实返回了4(RGB32)。所以我在加载bmp文件后添加了image.convertToFormat(QtGui.QImage.Format_Indexed8)。不过image.format还是返回4,颜色表还是废话。 @MichaelWestwort。请看我回答的第一行 ;-) convertToFormat() 函数不会进行就地修改。 也非常正确。所以我相应地修改了代码并创建了一个新图像。格式现在确实是 3 (Indexed8)。但是,颜色表仍然是 [4294967295L]*256。这是尽管 isGrayscale() 返回 true 并且颜色表包含所有 256 种灰度颜色(据我现在正确理解颜色是如何定义的)。 不,我错了。 isGrayscale 为 image2 返回 false,image2 在绘制时显示为全白色,但是读取所有像素会返回正确的红色、绿色和蓝色值,每个像素的三个值都相等。

以上是关于灰度图像的颜色表的主要内容,如果未能解决你的问题,请参考以下文章

直方图均衡化

16位图像的65536种颜色是指彩色,还是灰度(灰阶)?

如何将 RGB 图像转换为灰度但保留一种颜色? - 爪哇

如何使matlab图形的数据提示显示图像灰度颜色而不是其RGB值?

图像灰度化公式 颜色空间用途说明

如何更改灰度图像的 cairo 上下文源颜色