在 matplotlib 中生成 16 位颜色图
generate 16-bit color map in matplotlib
我想在 matplotlib 中使用 RGB colormap 为 16 位深度图像着色。从技术上讲,每个通道 8 位的 3 个通道应该足以为所有 2^16 个可能的深度值提供不同的 rgb 值。
标准颜色图 'viridis' 确实会产生 <1000 个不同的值,即使原始深度图像有两倍以上。
我尝试使用更多样本创建颜色图 plt.get_cmap('viridis', 2**16)
,但仍然不够。
一些代码来描述我正在尝试做的事情:
def depth_to_rgb(path):
depth_map = Image.open(path)
pixel = np.array(depth_map)
pixel = (pixel - np.min(pixel)) / np.ptp(pixel)
cm = plt.get_cmap('viridis', 2**16)
pixel_colored = np.uint8(np.rint(cm(pixel) * 255))[:, :, :3]
return Image.fromarray(pixel_colored)
我可以通过创建自定义 cm 稍微增加地图中不同值的数量,但仍然不够:
cm = mlp.colors.LinearSegmentedColormap.from_list("",
["red", "green", "yellow"], N=2**16)
是否有具有足够值的颜色图,或者我如何创建一个?
与 Pillow Image Library 相关的解决方案也很受欢迎。
编辑
显然(感谢 ImportanceOfBeingErnest)生成的颜色图确实有 2**16 个值,但 np.uint8(np.rint(cm(pixel) * 255))
导致其中一些落在相同的颜色上。我只打印了结果图像中不同颜色的数量。我想我必须做一些不同的映射,但原来的问题得到了回答。
Viridis 有 256 种颜色。它是一个 ListedColormap
,这意味着在重新采样时,它仍然会给你最大的初始颜色数。所以 plt.get_cmap('viridis', 2**16)
仍然会给你 256 种初始颜色。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
cmap = plt.get_cmap("viridis", 2**16)
a = cmap(np.linspace(0,1,2**16))
print(len(a))
print(len(np.unique(a, axis=0)))
打印
65536
256
但是 LinearSegmentedColormap.from_list
较大的 N 应该可以。
cmap = mcolors.LinearSegmentedColormap.from_list("", ["red", "green", "yellow"], N=2**16)
a = cmap(np.linspace(0,1,2**16))
print(len(a))
print(len(np.unique(a, axis=0)))
打印
65536
65536
如果你想要一个包含 2^16 个条目的 viridis 颜色图,你仍然可以在现有的 256 种颜色之间进行插值,
cmap = mcolors.LinearSegmentedColormap.from_list("", plt.cm.viridis.colors, N=2**16)
这将产生上述 65536 种颜色。
我想在 matplotlib 中使用 RGB colormap 为 16 位深度图像着色。从技术上讲,每个通道 8 位的 3 个通道应该足以为所有 2^16 个可能的深度值提供不同的 rgb 值。
标准颜色图 'viridis' 确实会产生 <1000 个不同的值,即使原始深度图像有两倍以上。
我尝试使用更多样本创建颜色图 plt.get_cmap('viridis', 2**16)
,但仍然不够。
一些代码来描述我正在尝试做的事情:
def depth_to_rgb(path):
depth_map = Image.open(path)
pixel = np.array(depth_map)
pixel = (pixel - np.min(pixel)) / np.ptp(pixel)
cm = plt.get_cmap('viridis', 2**16)
pixel_colored = np.uint8(np.rint(cm(pixel) * 255))[:, :, :3]
return Image.fromarray(pixel_colored)
我可以通过创建自定义 cm 稍微增加地图中不同值的数量,但仍然不够:
cm = mlp.colors.LinearSegmentedColormap.from_list("",
["red", "green", "yellow"], N=2**16)
是否有具有足够值的颜色图,或者我如何创建一个? 与 Pillow Image Library 相关的解决方案也很受欢迎。
编辑
显然(感谢 ImportanceOfBeingErnest)生成的颜色图确实有 2**16 个值,但 np.uint8(np.rint(cm(pixel) * 255))
导致其中一些落在相同的颜色上。我只打印了结果图像中不同颜色的数量。我想我必须做一些不同的映射,但原来的问题得到了回答。
Viridis 有 256 种颜色。它是一个 ListedColormap
,这意味着在重新采样时,它仍然会给你最大的初始颜色数。所以 plt.get_cmap('viridis', 2**16)
仍然会给你 256 种初始颜色。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
cmap = plt.get_cmap("viridis", 2**16)
a = cmap(np.linspace(0,1,2**16))
print(len(a))
print(len(np.unique(a, axis=0)))
打印
65536
256
但是 LinearSegmentedColormap.from_list
较大的 N 应该可以。
cmap = mcolors.LinearSegmentedColormap.from_list("", ["red", "green", "yellow"], N=2**16)
a = cmap(np.linspace(0,1,2**16))
print(len(a))
print(len(np.unique(a, axis=0)))
打印
65536
65536
如果你想要一个包含 2^16 个条目的 viridis 颜色图,你仍然可以在现有的 256 种颜色之间进行插值,
cmap = mcolors.LinearSegmentedColormap.from_list("", plt.cm.viridis.colors, N=2**16)
这将产生上述 65536 种颜色。