2017-07-18 173 views
3

我知道如何映射一个数字到颜色从这篇文章:Map values to colors in matplotlib如何解码matplotlib的Colormap中的颜色映射?

但我不知道如何解码映射得到我的原始颜色,假设这是一对一的映射,其中它一定是我的身影。

我为可视化目的编码图像,但我需要能够解码它并读取原始数据值。

仅供参考,这里有色彩图文档:http://matplotlib.org/api/cm_api.html

这里是我的尝试下面的主要答复,这仍然不工作的权利。

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] 
+0

这个问题已经被问了一个星期前[这里](https://stackoverflow.com/questions/45064969/go-from-rgb在matplotlib颜色地图),也是4年前[这里](https://stackoverflow.com/questions/14445102/invert-not-reverse-a-colormap-in-matplotlib)。两者都没有答案。也就是说,如果(a)知道它正在映射的数据范围,并且(b)如果知道已使用的颜色映射表,并且(c)颜色映射表是明确的,则可以颠倒颜色映射。我只是猜测人们懒得做这项工作,因为通常这个问题可以被规避。 – ImportanceOfBeingErnest

+0

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

+0

我在matplotlib关于它们映射的底层机制的坏文档中没有看到任何地方,但是如果它们是内射的,那么所有的数据(被编码的)都可以被恢复。你知道我在哪里可以找到这个信息,你为什么说它不是?这样做的原因是我们希望图像在1d中显示数组中值的特定颜色方案,然后使用除该图像以外的任何内容来获取我们的原始值。我们无法仅仅使用原始值来控制颜色。 –

回答

1

反相的colormapping是可能的,如果
(a)您知道的数据范围是映射和
(b)中,如果你知道,如果已经使用了颜色表,并
(c)中颜色映射是明确的。

以下函数将返回给定颜色,颜色映射和使用颜色映射的范围的值。

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) 

注意,此方法中包含错误的,所以你只能得到从最初被用来创建从地图颜色的颜色表,而不是值最接近的值。

在问题的更新代码中,您将颜色定义为每个通道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) 
+0

谢谢你的回应。我试图修改我的代码来处理这个问题,但它给了我一些奇怪的数字。也许你可以在我的代码中看到问题? (对不起,尝试去换新线,但已提交)请稍后看看更新后的帖子 –

+0

我更新了解决问题的答案。 – ImportanceOfBeingErnest

+0

谢谢,但错误不适合我。我不明白为什么没有办法找回确切的值 –

相关问题