gpt4 book ai didi

How to decode color mapping in matplotlib's Colormap?(如何在matplotlib的Colormap中解码颜色映射?)

转载 作者:bug小助手 更新时间:2023-10-24 23:22:35 27 4
gpt4 key购买 nike



I know how to map a number to a color from this post: Map values to colors in matplotlib

我从这篇文章中知道了如何将数字映射到颜色:在matplotlib中将值映射到颜色



But I don't know how to decode the mapping to get my original color, assuming this is a one-to-one mapping, which it must be I figure.

但我不知道如何解码贴图以获得我的原始颜色,假设这是一对一的贴图,我想这一定是一对一的贴图。



I am encoding an image for visualization purposes, but I need to be able to decode it and read the original data values.

出于可视化目的,我正在对图像进行编码,但我需要能够对其进行解码并读取原始数据值。



For reference, here are the Colormap docs: http://matplotlib.org/api/cm_api.html

以下是Colormap文档以供参考:http://matplotlib.org/api/cm_api.html



Here's my try to the main answer below, which still isn't working right.

以下是我对以下主要答案的尝试,它仍然不能正常工作。



from PIL import Image
import numpy as np
import matplotlib
import matplotlib.cm as cm
values = [670, 894, 582, 103, 786, 348, 972, 718, 356, 692]
minima = 103
maxima = 972
norm = matplotlib.colors.Normalize(vmin=minima, vmax=maxima, clip=True)
mapper = cm.ScalarMappable(norm=norm, cmap=cm.gist_rainbow_r)
c = []
for i in range(10):
c.append(mapper.to_rgba(values[i], bytes=True))
print(c) # [(75, 255, 0, 255), (255, 77, 0, 255), (0, 255, 64, 255), (255, 0, 191, 255), (255, 250, 0, 255), (0, 72, 255, 255), (255, 0, 40, 255), (151, 255, 0, 255), (0, 83, 255, 255), (108, 255, 0, 255)]

def get_value_from_cm(color, cmap, colrange):
# color = matplotlib.colors.to_rgba(color)
r = np.linspace(colrange[0], colrange[1], 10) # there are 10 values
norm = matplotlib.colors.Normalize(colrange[0], colrange[1])
mapvals = cmap(norm(r))[:, :4] # there are 4 channels: r,g,b,a
distance = np.sum((mapvals - color) ** 2, axis=1)
return r[np.argmin(distance)]

decoded_colors = []
for i in range(10):
decoded_colors.append(get_value_from_cm(c[i], cm.gist_rainbow_r, colrange=[minima, maxima]))
print(decoded_colors) # [778.88888888888891, 778.88888888888891, 489.22222222222223, 103.0, 778.88888888888891, 392.66666666666669, 103.0, 778.88888888888891, 392.66666666666669, 778.88888888888891]

更多回答

That question has already been asked a week ago here and also 4 years ago here. Both do not have an answer. That said, inverting the colormapping is possible, if (a) you know the data range it is mapping and (b) if you know the colormap that has been used, and (c) if the colormap is unambiguous. I just guess that people are too lazy to do the work, because usually that problem can be circumvented.

这个问题在一周前和4年前就已经在这里被提出了。这两个问题都没有答案。也就是说,如果(A)您知道它正在映射的数据范围,(B)如果您知道已经使用的色彩映射表,以及(C)如果色彩映射表是明确的,则可以反转色彩映射。我只是猜测,人们太懒了,不愿做这项工作,因为这个问题通常是可以绕过的。

Decoding the image is an imprecise way to recover the data -- normally you save the original data (and the code needed to generate a published image) and access that.

解码图像是恢复数据的一种不精确的方式--通常您保存原始数据(以及生成发布图像所需的代码)并访问该数据。

I don't see anywhere in matplotlib's bad docs about the underlying mechanism for their mappings but if they are injective, all data (that was encoded) can be recovered. Do you know where I can find this info and why you are saying it is not? The reason for doing it this way is that we want an image to show a specific color scheme in 1d for values in an array and then using nothing but that image to get our original values. We can't control colors just using the raw values.

我在matplotlib的糟糕文档中看不到任何关于其映射的底层机制的内容,但如果它们是内射的,则所有数据(已编码)都可以恢复。你知道我在哪里可以找到这些信息吗?为什么你说它不是?这样做的原因是,我们希望图像以一维的形式显示数组中的值的特定配色方案,然后只使用该图像来获得原始值。我们不能仅使用原始值来控制颜色。

优秀答案推荐

Inverting the colormapping is possible, if

(a) you know the data range it is mapping and

(b) if you know the colormap that has been used, and

(c) if the colormap is unambiguous.

如果(A)您知道它正在映射的数据范围,(B)如果您知道已使用的色彩映射表,(C)如果色彩映射表是明确的,则可以反转色彩映射。



The following function would return the value given a color, a colormap and the range over which the colormap has been used.

以下函数将在给定颜色、色彩映射表和使用色彩映射表的范围的情况下返回值。



import numpy as np
import matplotlib.colors
import matplotlib.pyplot as plt

def get_value_from_cm(color, cmap, colrange=[0.,1.]):
color=matplotlib.colors.to_rgb(color)
r = np.linspace(colrange[0],colrange[1], 256)
norm = matplotlib.colors.Normalize(colrange[0],colrange[1])
mapvals = cmap(norm(r))[:,:3]
distance = np.sum((mapvals - color)**2, axis=1)
return r[np.argmin(distance)]


b = get_value_from_cm(plt.cm.coolwarm(0.5), plt.cm.coolwarm, [0.,1.])
c = get_value_from_cm(np.array([1,0,0]), plt.cm.coolwarm)

print b # 0.501960784314
print plt.cm.coolwarm(b)
# (0.86742763508627452, 0.86437659977254899, 0.86260246201960789, 1.0)
print plt.cm.coolwarm(0.5)
#(0.86742763508627452, 0.86437659977254899, 0.86260246201960789, 1.0)


Note that this method involves an error, so you only get the closest value from the colormap and not the value that has initially been used to create the color from the map.

请注意,此方法包含错误,因此您只能从色彩映射表中获得最接近的值,而不是最初用于从映射表中创建颜色的值。



In the updated code from the question, you have the color defined as integers between 0 and 255 for each channel. You therefore need to first map those to the range 0 to 1.

在问题的更新代码中,您将每个通道的颜色定义为0到255之间的整数。因此,您需要首先将它们映射到0到1的范围。



from PIL import Image
import numpy as np
import matplotlib
import matplotlib.cm as cm
values = [670, 894, 582, 103, 786, 348, 972, 718, 356, 692]
minima = 103
maxima = 972
norm = matplotlib.colors.Normalize(vmin=minima, vmax=maxima, clip=True)
mapper = cm.ScalarMappable(norm=norm, cmap=cm.gist_rainbow_r)
c = []
for i in range(10):
c.append(mapper.to_rgba(values[i], bytes=True))
print(c) # [(75, 255, 0, 255), (255, 77, 0, 255), (0, 255, 64, 255), (255, 0, 191, 255), (255, 250, 0, 255), (0, 72, 255, 255), (255, 0, 40, 255), (151, 255, 0, 255), (0, 83, 255, 255), (108, 255, 0, 255)]

def get_value_from_cm(color, cmap, colrange):
color = np.array(color)/255.
r = np.linspace(colrange[0], colrange[1], 256)
norm = matplotlib.colors.Normalize(colrange[0], colrange[1])
mapvals = cmap(norm(r))[:, :4] # there are 4 channels: r,g,b,a
distance = np.sum((mapvals - color) ** 2, axis=1)
return r[np.argmin(distance)]

decoded_colors = []
for i in range(10):
decoded_colors.append(get_value_from_cm(c[i], cm.gist_rainbow_r, colrange=[minima, maxima]))
print(decoded_colors)

更多回答

Thank you for the response. I tried to modify my code to work with that, but it's giving me some weird numbers. Maybe you can see the problem in my code? (Sorry, tried going to new line but it submitted) Please look at the updated post in a minute

感谢您的回复。我试图修改我的代码以使用它,但它给了我一些奇怪的数字。也许您可以在我的代码中看到这个问题?(对不起,试着跳到新的行但提交了)请立即查看更新的帖子

I updated the answer with the solution to your problem.

我用您的问题的解决方案更新了答案。

thanks but the error does not work for me. i dont understand why there isnt a way to get back exact values

谢谢,但这个错误对我不起作用。我不明白为什么没有办法找回准确的值

Sorry, you changed my original code to replace the 256 by the number 10 in the linspace and I blindly took that over for the second version. This needs to stay 256 of course. The error can then be as large as (972-103)/256. = 3.3; so you can recover the values with an error of ~+/-3. This is due to the resolution of the colormap, which has 256 colors in it.

对不起,您更改了我的原始代码,将linspace中的256替换为数字10,我盲目地将其替换为第二个版本。当然,这需要保持256。这样,误差就可以达到(972-103)/256。=3.3;因此您可以恢复误差为~+/-3的值。这是由于色彩映射表的分辨率,其中有256种颜色。

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com