use*_*764 9 python image matplotlib scipy
如何反转颜色映射图像?
我有一个2D图像,它在彩色图上绘制数据.我想读取图像并"反转"颜色贴图,即查找特定的RGB值,然后将其转换为浮点数.
例如:使用此图片:http://matplotlib.sourceforge.net/_images/mri_demo.png
我应该能够获得一个440x360浮点矩阵,知道色彩映射是cm.jet
from pylab import imread
import matplotlib.cm as cm
a=imread('mri_demo.png')
b=colormap2float(a,cm.jet) #<-tricky part
Run Code Online (Sandbox Code Playgroud)
可能有更好的方法来做到这一点; 我不确定.如果您阅读,help(cm.jet)您将看到用于将区间[0,1]中的值映射到RGB 3元组的算法.你可以用一点纸和铅笔计算公式,以反转定义映射的分段线性函数.
然而,有许多问题使得纸和铅笔解决方案有些缺乏吸引力:
这是一个很费力的代数,解决方案是针对cm.jet的.如果更改颜色贴图,则必须再次完成所有这些工作.如何自动解决这些代数方程很有意思,但这不是我知道如何解决的问题.
通常,颜色图可能不是可逆的(多于一个值可以映射到相同的颜色).例如,在cm.jet的情况下,0.11和0.125之间的值都映射到RGB 3元组(0,0,1).因此,如果您的图像包含纯蓝色像素,则无法判断它是来自值0.11还是值,例如0.125.
由于非唯一性问题以及投影/插值问题,您可能会遇到许多可能的解决方案.以下只是一种可能性.
以下是解决唯一性和投影/插值问题的一种方法:
创建一个gradient充当"代码簿"的代码.这gradient是cm.jet颜色映射中的RGBA 4元组数组.颜色gradient对应于0到1之间的值.使用scipy的矢量量化函数scipy.cluster.vq.vq将图像中的所有颜色mri_demo.png映射到最近的颜色gradient.由于颜色贴图可以对许多值使用相同的颜色,因此渐变可以包含重复的颜色.我将其留待scipy.cluster.vq.vq决定哪个(可能)非唯一的代码簿索引与特定颜色相关联.
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
import scipy.cluster.vq as scv
def colormap2arr(arr,cmap):
# http://stackoverflow.com/questions/3720840/how-to-reverse-color-map-image-to-scalar-values/3722674#3722674
gradient=cmap(np.linspace(0.0,1.0,100))
# Reshape arr to something like (240*240, 4), all the 4-tuples in a long list...
arr2=arr.reshape((arr.shape[0]*arr.shape[1],arr.shape[2]))
# Use vector quantization to shift the values in arr2 to the nearest point in
# the code book (gradient).
code,dist=scv.vq(arr2,gradient)
# code is an array of length arr2 (240*240), holding the code book index for
# each observation. (arr2 are the "observations".)
# Scale the values so they are from 0 to 1.
values=code.astype('float')/gradient.shape[0]
# Reshape values back to (240,240)
values=values.reshape(arr.shape[0],arr.shape[1])
values=values[::-1]
return values
arr=plt.imread('mri_demo.png')
values=colormap2arr(arr,cm.jet)
# Proof that it works:
plt.imshow(values,interpolation='bilinear', cmap=cm.jet,
origin='lower', extent=[-3,3,-3,3])
plt.show()
Run Code Online (Sandbox Code Playgroud)
您看到的图像应该接近于再现mri_demo.png:

(原始mri_demo.png有一个白色边框.由于白色不是cm.jet中的颜色,请注意scipy.cluster.vq.vq将白色映射到gradient代码簿中的最近点,这恰好是淡绿色.)
| 归档时间: |
|
| 查看次数: |
3887 次 |
| 最近记录: |