灰度图像的颜色表
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 在绘制时显示为全白色,但是读取所有像素会返回正确的红色、绿色和蓝色值,每个像素的三个值都相等。以上是关于灰度图像的颜色表的主要内容,如果未能解决你的问题,请参考以下文章