如何使用Qt为16位灰度图像着色?
我有一个16位灰度如何使用Qt为16位灰度图像着色?,qt,image-processing,qimage,image-formats,Qt,Image Processing,Qimage,Image Formats,我有一个16位灰度QImage::Format_Grayscale16的无符号短值在内存中连续。将其转换为pixmap后,它将正确显示在QLabel上。我现在需要使用一个给定的颜色表对其进行着色,该颜色表将强度映射到特定的RGB值: QVector<QRgb> table_16; for (double i = 0; i < 4096; ++i) { table_16.append(qRgb( (int)std::round(std::clamp( -
QImage::Format_Grayscale16
的无符号短
值在内存中连续。将其转换为pixmap后,它将正确显示在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);
QVector表_16;
对于(双i=0;i<4096;++i){
表16.追加(qRgb)(
(内部)标准:圆形(标准:夹具(-4*std::abs(i-4095.0*3/4)+4095.0*3/2,0.0,4095.0)),
(int)标准:圆形(标准:夹具(-4*std::abs(i-4095.0*2/4)+4095.0*3/2,0.0,4095.0)),
(int)标准圆形(标准夹具(-4*std::abs(i-4095.0*1/4)+4095.0*3/2,0.0,4095.0));
}
表16[0]=qRgb(4095,4095,4095);
注意:图像实际上是12位的,但存储方式与16位图像相同。因此,RGB映射的限制为4096
不幸的是,我遇到了麻烦。首先,转换为RGB16格式是否正确?我已经发布了另一个非常类似的问题,但对于8位灰度。setColorTable()
的Qt文档说明:
仅单色和8位格式
所以我假设我不能用这个来处理我的16位图像。最好的做法是缩小比例并转换为8位吗?任何性能优化都会很好,因为图像应该是实时流的。一个非常昂贵的解决方案如下: 使用convertToFormat(QImage::Format\u Grayscale8)创建新的8位图像 通过创建格式为
Indexed8
的QImage,设置其颜色表,并将8位QImage数据复制到此新的Indexed8
格式图像来着色。有关更多详细信息,请参见我的另一个问题
这是可行的,但如果有人知道一种更快的方法,请随意回答。这似乎有很多复制品。我已经必须遍历图像一次,才能将12位映射到16位范围。qRgb(int,int,int)
创建一个qRgb
,它每个通道存储8位(而参数是int,)。将接受(并使用)16位值来创建具有必要精度的QRgb64
不幸的是,还没有一个QImage::Format_Indexed16
(请参阅)解释为什么Qt不直接支持16位灰度的颜色表。如果您不需要低8位的对比度数据(或者在您的情况下仅需要4位,因为只有高12位具有真实数据),并且颜色表始终相同,那么转换为格式索引8
并使用颜色表将是最简单的方法
如果您确实需要低位中的对比度数据,则需要在8位每通道RGB上手动缩放这12位。创建具有相同宽度/高度的新QImage
,并逐像素循环原始数据。是一个Qt库,其中包含各种算法的示例,这些算法试图保持对比度(免责声明,我写的)