2013-10-17 28 views
6

Micro-Manager 1.4を使用して顕微鏡用のカメラで遊んでいます。 Pythonインターフェイスを使用して、私はカメラにアクセスし、露出時間などを変更し、個々の画像をキャプチャすることができました。Pythonで単一整数ピクセルの配列をRGBトリプレットに変換する

しかし、各画像はNumPy配列として返されます。各ピクセルは単一の整数として表されます。 "7765869"。私の知る限り、オンラインで見つけることができるように、これはJavaで「BufferedImageの」として知られ、そしてとしては、RGB値が符号化されていることを意味します。私の質問がある

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

:どのように私は、例えば使用することができますNumpyまたはOpenCVの場合、この種の配列を、各ピクセルがuint8値のRGBトリプレットであるより便利な配列に変換しますか?言うまでもなく、変換は可能な限り効率的でなければなりません。

+0

は何を持っていることは、フォームの線形ディオファントス方程式 '* X + B * Y + C * Z == N '、 私たちの場合は'で、この背後にある理論ビットに拡張するにはa = 2 ** 16、b = 2 ** 8、c = 1 'となる。一般に、これらの方程式の解は、 'gcd(a、b、c)'を見つけ、 'n'を分割することを望む。そうでなければ、解決策はありません。ソリューションが存在する場合、無限に多くのソリューションが存在します。しかし、この場合、解「0 <= x、y、z <256」を見つけるために制限されているので、 'gcd(a、b、c)| n。 – wflynny

答えて

6

最も簡単で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()を追加する必要があります上記のコードが避けていたデータのコピーをトリガーします。

+0

完璧に動作します! "img2"を "img.view(np.uint8).reshape(img.shape +(4、))[...、:3]"として定義し、 "cv2.imwrite"を使用すると完全に画像が保存されます。ありがとう! – Bjarke

+0

@Bjarke BGRではなくRGBイメージを保存することをお勧めします。システムのエンディアンに依存します。それが間違っているならば、単に '' :: :: 1 ''をあなたの' 'img2'の定義の最後につけておけば、読み込まれる順序を逆にします。 – Jaime

+0

非常に巧妙な解決策! – tom10

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

少なくとも私は...上記の式私の知る限り

多少読みやすく私にある
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 

として書かれており、

2
上で何が起こっているかをクリアすることができると思います

片道は

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

しかし、私はそれが最もエレガントな(Pythonic?)または最速の方法だとは思わない。

0

最速のアプローチは、おそらくnumpyの中でこれを維持するために、次のようになります。

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])) 
関連する問題