繁体   English   中英

将灰度二维 numpy 数组转换为 RGB 图像

[英]Convert grayscale 2D numpy array to RGB image

我有一个灰度“TIF”图像,我将其读取为 numpy 数组,它是 2D

我的二维阵列中的像素强度范围为 17 到 317。

我有两个挑战

  1. 将此二维数组转换为 RGB 图像

  2. 将像素强度(17 到 317 之间)缩放为 RGB 值并将灰度图像显示为 RGB 彩色图像

灰度图像

不幸的是,我不能使用 Opencv 和 Matplotlib,因为我正在使用的最终产品不支持这些

在我看来,您的问题有 3 个方面:

  • 创建颜色图或 LUT “查找表”
  • 将像素缩放到标准范围
  • 将颜色图应用于没有matplotlib的图像。

因此,要创建颜色图,我们需要一个包含 256 个 RGB 值的列表,我们可以在其中查找任何灰度值并找到我们想要将其显示为的颜色。 我知道您不能在生产中使用matplotlib ,但您可以从其他机器上获取一两个颜色图并将其复制到您的生产机器上。 那么,让我们这样做吧。 我们将采用viridis颜色图:

#!/usr/bin/env python3

import numpy as np
from matplotlib import cm

# Get 256 entries from "viridis" or any other Matplotlib colormap
colmap = cm.get_cmap('viridis', 256)

# Make a Numpy array of the 256 RGB values
# Each line corresponds to an RGB colour for a greyscale level
np.savetxt('cmap.csv', (colmap.colors[...,0:3]*255).astype(np.uint8), fmt='%d', delimiter=',')

如果我们查看那个文件"cmap.csv" ,它有 256 行并且像这样开始:

68,1,84
68,2,85
68,3,87
69,5,88
69,6,90
69,8,91
70,9,92
...
...

这意味着我们在灰度图像中看到0的任何地方,我们实际上为像素rgb(68,1,86) 我们在灰度中看到1的任何地方都映射到rgb(68,2,85) 大概您可以将该文件复制到您的生产机器,您可以选择Matplotlib的任何一个颜色图。


关于缩放比例,您发布的是范围为 0..117 的 8 位 PNG 图像,而不是范围为 17..317 的 16 位 TIFF 图像,因此这不是最有帮助的。 此外,您还没有说明您打算如何在没有OpenCVmatplotlib的系统上读取 TIFF,所以我不知道您是否有PIL/Pillow或计划使用tifffile

相反,我将创建一个范围为 17..317 的虚拟 32x32 图像,如下所示:

grey = np.random.randint(17,318, (32,32))

看起来像这样:

array([[244,  75, 237, ..., 154, 190,  70],
       [286, 247, 158, ..., 150, 267, 124],
       [170, 305, 237, ..., 126, 111, 236],
       ...,
       [163, 292, 184, ...,  24, 253, 177],
       [314,  34,  36, ...,  87, 316, 182],
       [258, 153, 278, ..., 189,  57, 196]])

如果我们现在想将其从 17..317 范围缩放到 0..255 范围内,我们可以使用:

rescaled = ((grey.astype(float) - grey.min())*255/(grey.max() - grey.min())).astype(np.uint8)

这给了我们这个:

array([[192,  49, 187, ..., 116, 147,  45],
       [228, 195, 119, ..., 113, 212,  90],
       [130, 244, 187, ...,  92,  79, 186],
       ...,
       [124, 233, 141, ...,   5, 200, 136],
       [252,  14,  16, ...,  59, 254, 140],
       [204, 115, 221, ..., 146,  34, 152]], dtype=uint8) 

查找可以通过加载包含我们的颜色图的 CSV 文件来完成,并从颜色图中获取相应的元素,这些元素由 0...255 范围内的灰度值索引:

#!/usr/bin/env python3

import numpy as np
from PIL import Image

# Load image as greyscale and make into Numpy array
grey = np.array(Image.open('TdoGc.png').convert('L'))

# Load RGB LUT from CSV file
lut = np.loadtxt('cmap.csv', dtype=np.uint8, delimiter=',')

# Make output image, same height and width as grey image, but 3-channel RGB
result = np.zeros((*grey.shape,3), dtype=np.uint8)

# Take entries from RGB LUT according to greyscale values in image
np.take(lut, grey, axis=0, out=result)

# Save result
Image.fromarray(result).save('result.png')

在此处输入图像描述

如果您在读取后将灰度图像缩放到整个范围,请使用以下行:

grey = ((grey.astype(float) - grey.min())*255/(grey.max() - grey.min())).astype(np.uint8)

你会得到这个:

在此处输入图像描述


如果您想可视化您的颜色图,请将上面的行更改为如下所示:

grey = np.array(Image.open('TdoGc.png').convert('L'))

进入这个,以便它生成一个渐变(斜坡)图像:

grey = np.repeat(np.arange(256,dtype=np.uint8).reshape(1,-1), 100, axis=0)

然后你可以看到你的颜色图:

在此处输入图像描述


一个快速处理没有 class 变量枚举颜色的分段线性颜色图的技巧。 因此,您可以像这样从autumn色彩图中制作cmap.csv文件:

import numpy as np
from matplotlib import cm

# Get "autumn" colourmap
colmap = cm.get_cmap('autumn')

# Save 256 RGB entries as CSV - one for each of grey levels 0..255
np.savetxt('cmap.csv', np.array([colmap(i/255)[:3] for i in range(256)]) * 255, fmt="%d", delimiter=',')

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM