如何将彩色地图图像反转为标量值 [英] how to reverse color map image to scalar values

查看:120
本文介绍了如何将彩色地图图像反转为标量值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何反转颜色映射图像?

How do I invert a color mapped image?

我有一个2D图像,它在彩色图上绘制数据。我想读取图像并反转颜色图,即查找特定的RGB值,然后将其转换为浮点数。

I have a 2D image which plots data on a colormap. I'd like to read the image in and 'reverse' the color map, that is, look up a specific RGB value, and turn it into a float.

例如:
使用此图片: http://matplotlib.sourceforge.net/_images/mri_demo.png

我应该能够获得一个440x360的浮动矩阵,知道colormap是cm.jet

I should be able to get a 440x360 matrix of floats, knowing the colormap was cm.jet

from pylab import imread
import matplotlib.cm as cm
a=imread('mri_demo.png')
b=colormap2float(a,cm.jet) #<-tricky part


推荐答案

可能有更好的方法来做到这一点;我不确定。
如果您阅读 help(cm.jet),您将看到用于将区间[0,1]中的值映射到RGB 3元组的算法。你可以用一点纸和铅笔计算公式来反转定义映射的分段线性函数。

There may be better ways to do this; I'm not sure. If you read help(cm.jet) you will see the algorithm used to map values in the interval [0,1] to RGB 3-tuples. You could, with a little paper and pencil, work out formulas to invert the piecewise-linear functions which define the mapping.

然而,有许多问题使得纸和笔的解决方案有点没吸引力:

However, there are a number of issues which make the paper and pencil solution somewhat unappealing:


  1. 这是一个很费力的代数,而b $ b解决方案是针对特定的cm.jet。
    如果你改变颜色图,你必须再次完成所有这些工作
    。如何自动解决这些代数方程很有意思,但不是我知道如何解决的问题。

  1. It's a lot of laborious algebra, and the solution is specific for cm.jet. You'd have to do all this work again if you change the color map. How to automate the solving of these algebraic equations is interesting, but not a problem I know how to solve.

一般来说,颜色图可能不是
可逆(多个值可以将
映射到相同的颜色)。在cm.jet的
情况下,例如,0.11
和0.125之间的值都映射到RGB
3元组(0,0,1)。因此,如果
你的图像包含一个纯蓝色
像素,那么实际上没有办法
告诉它是来自0.11
的值还是0.125的值。

In general, the color map may not be invertible (more than one value may be mapped to the same color). In the case of cm.jet, values between 0.11 and 0.125 are all mapped to the RGB 3-tuple (0,0,1), for example. So if your image contains a pure blue pixel, there is really no way to tell if it came from a value of 0.11 or a value of, say, 0.125.

由于非唯一性问题,以及投影/插值问题,可以为您提出的问题提供许多可能的解决方案。以下是一种可能性。

Due to the non-uniqueness issue, and the projection/interpolation issue, there can be many possible solutions to the problem you pose. Below is just one possibility.

以下是解决唯一性和投影/插值问题的一种方法:

Here is one way to resolve the uniqueness and projection/interpolation issues:

创建一个渐​​变,它充当代码簿。 渐​​变是cm.jet颜色映射中的RGBA 4元组数组。 渐​​变的颜色对应于0到1之间的值。使用scipy的矢量量化函数 scipy.cluster.vq.vq 将图像中的所有颜色mri_demo.png映射到最近的渐​​变中的颜色。
由于颜色贴图可能对许多值使用相同的颜色,因此渐变可能包含重复的颜色。我将它留给 scipy.cluster.vq.vq 来决定哪个(可能)非唯一的代码簿索引与特定颜色相关联。

Create a gradient which acts as a "code book". The gradient is an array of RGBA 4-tuples in the cm.jet color map. The colors of the gradient correspond to values from 0 to 1. Use scipy's vector quantization function scipy.cluster.vq.vq to map all the colors in your image, mri_demo.png, onto the nearest color in gradient. Since a color map may use the same color for many values, the gradient may contain duplicate colors. I leave it up to scipy.cluster.vq.vq to decide which (possibly) non-unique code book index to associate with a particular color.

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()

你看到的图像应该接近于再现mri_demo.png:

The image you see should be close to reproducing mri_demo.png:

(原始的mri_demo.png有一个白色边框。由于白色不是cm.jet中的颜色,请注意 scipy.cluster.vq.vq 贴图白色到渐​​变代码簿中的最近点,恰好是浅绿色。)

(The original mri_demo.png had a white border. Since white is not a color in cm.jet, note that scipy.cluster.vq.vq maps white to to closest point in the gradient code book, which happens to be a pale green color.)

这篇关于如何将彩色地图图像反转为标量值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆