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

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

问题描述

如何反转彩色映射的图像?

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

For example: using this image: http://matplotlib.sourceforge.net/_images/mri_demo.png

知道颜色图是cm.jet,我应该能够得到440x360的浮点数矩阵

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三元组的算法.您只需一点纸和铅笔,就可以计算出公式来反转定义映射的分段线性函数.

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. 这是很多费力的代数,并且 该解决方案特定于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 例如三元组(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:

创建一个gradient作为代码本". gradient是cm.jet颜色图中的RGBA 4元组的数组. gradient的颜色对应于从0到1的值.使用scipy的矢量量化功能

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将白色映射到gradient代码簿中的最接近点,碰巧是苍白的绿色.

(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天全站免登陆