在Python中将单个整数像素的数组转换为RGB三元组

时间:2013-10-17 16:36:31

标签: python opencv numpy camera

我正在玩一台使用Micro-Manager 1.4的显微镜相机。使用Python界面,我设法访问相机,更改曝光时间等,我可以捕获单个图像。

然而,每个图像作为NumPy数组返回,其中每个像素表示为单个整数,例如, “7765869”。据我所知,这在Java中被称为“BufferedImage”,它意味着RGB值被编码为:

BufferedImage = R * 2^16 + G * 2^8 + B

我的问题是:我怎样才能使用例如Numpy或OpenCV,将这种数组转换为更方便的数组,其中每个像素是uint8值的RGB三元组?毋庸置疑,转换应该尽可能高效。

4 个答案:

答案 0 :(得分:7)

最简单的是让numpy为你做转换。你的numpy数组可能是np.uint32类型。如果您将其视为np.uint8数组,您将拥有RGB0格式图像,即每个像素的R,G和B值,以及后面的空np.uint8。重塑和丢弃零值很容易:

>>> img = np.array([7765869, 16777215], dtype=np.uint32)
>>> img.view(np.uint8)
array([109, 127, 118,   0, 255, 255, 255,   0], dtype=uint8)
>>> img.view(np.uint8).reshape(img.shape+(4,))[..., :3]
array([[109, 127, 118],
       [255, 255, 255]], dtype=uint8)

最好的事情是没有计算或复制数据,只是重新解释原始图像的内容:我认为你不能比这更有效率!

我记得对于某些操作,OpenCV需要一个连续的数组,所以你可能不得不在该表达式的末尾添加一个.copy()来真正摆脱零列,而不是简单地忽略它,尽管这个当然会触发上面代码避免的数据副本。

答案 1 :(得分:2)

一种方法是

Red = BufferedImage / 2**16
Green = (BufferedImage % 2**16) / 2**8
Blue = (BufferedImage % 2**8)

然而,我怀疑它是最优雅的(Pythonic?)还是最快的方式。

答案 2 :(得分:0)

rgbs = [((x&0xff0000)>>16,(x&0xff00)>>8,x&0xff) for x in values]

至少我认为......

afaik上面的公式也可以写成

BufferedRGB = RED<<16 + GREEN << 8 + BLUE 

red,green,blue = 0xFF,0x99,0xAA
red<<16 + green << 8 + blue  #= 0xFF99AA (buffered into one value)

#apply a bitmask to get colors back
red = (0xFF99AA & 0xFF0000) >> 16 # = 0xFF
green = (0xFF99AA & 0xFF00) >> 8  # = 0x99
blue = 0xFF99AA & 0xFF          # = 0xAA

这对我来说更具可读性并清楚发生了什么

答案 3 :(得分:0)

最快的方法可能是保持这种状态:

from numpy import *
x = array([211*2**16 + 11*2**8 + 7])  # test data

b, g, r = bitwise_and(x, 255), bitwise_and(right_shift(x, 8), 255), bitwise_and(right_shift, 16), 255)

print r, g, b
(array([211]), array([11]), array([7]))