pyplot.cm 实例对相同值但不同数据类型产生不同结果

1 投票
2 回答
2122 浏览
提问于 2025-04-17 15:54

这个问题是接着 tcaswell 提供的解决方案(答案 #2)来讨论的,原问题是:有没有办法把 pyplot.imshow() 对象转换成 numpy 数组?

考虑以下的 Python 代码:

import pylab
import numpy as np

a = np.array( ( 30, 129 ) , dtype = np.float32 )
b = np.array( ( 30, 129 ) , dtype = np.int32 )
my_cm = pylab.cm.get_cmap('jet')
a_mapped_data = my_cm( a )
b_mapped_data = my_cm( b )

我使用了一个小数组来节省空间,但即使使用大数组也是这样。

结果是:

>>> a
array([  30.,  129.], dtype=float32)

>>> b
array([ 30, 129])

>>> a_mapped_data
array([[ 0.5,  0. ,  0. ,  1. ],
       [ 0.5,  0. ,  0. ,  1. ]])

>>> b_mapped_data
array([[ 0.        ,  0.        ,  1.        ,  1.        ],
       [ 0.5028463 ,  1.        ,  0.46489564,  1.        ]])

我似乎不太明白这里的情况。尽管值是相同的,cm.get_map() 实例却对 numpy.int32numpy.float32 数据类型产生了不同的结果。上面的代码有什么问题吗?请帮我解决这个问题。我需要绘制类型为 numpy.float 的 2D 数组。

我在 Windows7 x64 家庭基本版上使用的是 Python 2.7.3 32位。

2 个回答

0

下面的脚本对输入数据进行了颜色映射,并将这个映射直接转换成图像,而没有使用 pylab.imshowpylab.pcolor,也没有添加任何刻度或边框。

import pylab
import numpy as np

a = np.random.random( (512, 512) )*100
# a is a 2D array of random data not in the range of 0.0 to 1.0

# normalize the data
normed_a = ( a - a.min() )/( a.max() - a.min() )

# now create an instance of pylab.cm.get_cmap()
my_cm = pylab.cm.get_cmap('jet_r')

# create the map
mapped_a = my_cm( normed_a )

# to display the map, opencv is being used
# import opencv
import cv2 as cv

# convert mapped data to 8 bit unsigned int
mapped_au8 = (255 * mapped_a).astype('uint8')

# show the image
cv.imshow( 'a', mapped_au8 )
cv.waitKey( 0 )
cv.destroyAllWindows()

编辑: cm.get_cmap 返回的类型是 RGBA 格式,但 OpenCV 默认使用的是 BGR 格式。因此,在显示通过 cm.get_cmap() 返回值转换得到的图像之前,需要将其转换为 BGR 格式(在 OpenCV 中,显示图像之前,ALPHA 通道会默认被去掉,所以除非必要,不用把它转换成 BGRA)。下面的代码提供了更好的解释:

mapped_au8 = (255 * mapped_a).astype('uint8')

#convert mapped_au8 into BGR fromat before display
mapped_u8 = cv.cvtColor( mapped_au8, cv.COLOR_RGBA2BGR )

# show the image
cv.imshow( 'a', mapped_au8 )
cv.waitKey( 0 )
cv.destroyAllWindows()

这个回答是作为对问题的 编辑 发布的,问题是 pyplot.cm 实例对相同值但不同数据类型产生不同结果,由提问者 Yash 提出,遵循 CC BY-SA 3.0 许可协议。

2

来自 my_cm.__call__ 的文档说明:

*X* is either a scalar or an array (of any dimension).
If scalar, a tuple of rgba values is returned, otherwise
an array with the new shape = oldshape+(4,). If the X-values
are integers, then they are used as indices into the array.
If they are floating point, then they must be in the
interval (0.0, 1.0).
Alpha must be a scalar between 0 and 1, or None.
If bytes is False, the rgba values will be floats on a
0-1 scale; if True, they will be uint8, 0-255.

注意浮点数和整数的处理方式是不同的。

撰写回答