2012-05-09 17 views
2

私はデータ型 "> u2"(ビッグエンディアン、符号なし、2バイト/ 16ビット)のnumpy配列を出力する外部ライブラリを使用しています。私の場合、10ビットのみが有効です(出力は、実際にリトルエンディアンを出力するハードウェアデバイスからのものです)。たとえば、Pythonでの高速/組み込みビット操作/ numpy?

は、直接的なpython出力としてbin(65283)=0b1111111100000011に対応し、リトルエンディアンの場合は00001111111111に対応します。

ライブラリーから出力された0-65283の範囲を、10ビットハードウェア機能に適した範囲0-1023にマップしたいとします。これはどうすればいいですか?

私は次のことを試してみた:

>>>import numpy as np 

>>>arr=np.array([65283, 6528, 652, 65, 6], dtype=">u2") 
>>>print arr/64 # same as arr/2**6 and arr >> 6 
[1020 102 10 1 0] 
>>>print arr.byteswap() 
[ 1023 32793 35842 16640 1536] 

しかし、これは、所望の結果を与えるものではありません。私が見つけたのは、bin()関数がビッグエンディアン形式(このnumpyの配列の場合)で出力されますが、パディングされた0は省略されています。たとえば、65283はすべての16ビットを表しますが、bin(6528)=0b1100110000000(真ん中に3つのゼロがありません)。

これを修正して10ビットのリトルエンディアンの数値を返すには、6528のバイナリ形式を取得し、真ん中に3つのゼロを追加し、バイトスワップを実行します。しかし、1)これは非常に退屈であり(要素ごとに行われる)、2)ゼロパディングが矛盾している(例えば、652にはさらに6つのゼロが必要)。

これを行うための組み込み方法はありますか? structモジュール(w/packおよび/またはunpack)のように見えますが、今はギリシャ語です。どんな助けもありがとう!

EDIT

私は犯人を見つけたと信じています。上の私の例(65238のカメラ/ライブラリからの実際の値をとり、半分恣意的な追加値を仮定すると、右端の数字は明らかに削除されています)は起こりません!例えば6528は、最下位バイト(00011001**1**0000000)に1を必要とし、これは起こりません(10ビットだけが有効です)。

さらに検査すると、私のコードでarr.byteswap()arrに正当な値がある)という単純なものが動作します。例:

>>>arr=np.array([12288, 13312, 12800, 12032, 13312, 13824, 65283, 0, 7936], dtype=">u2") 
>>>arr.byteswap() 
array([ 48, 52, 50, 47, 52, 54, 1023, 0, 31], dtype=uint16) 

実際にこのコードで試したことはありません。混乱させて申し訳ありません。しかし、うまくいけば、それは(あなたがのBaslerカメラを使用する場合は特に!)他の誰かがこの問題を回避つまずき役立つかもしれない、私は推測些細なことが判明した...

いっそ

答えて

0
import struct 
struct.pack('<H',val) 

または、:

>>> arr.byteswap().newbyteorder() 
array([65283, 6528, 652, 65,  6], dtype=uint16) 
>>> arr.byteswap().newbyteorder().tostring() 
'\x03\xff\x80\x19\x8c\x02A\x00\x06\x00' 

docs

+0

Hmm。 'arr.byteswap()。newbyteorder()。tostring()'からの戻り値を使って10ビットのuint16(またはint16)にするにはどうすればよいですか? (ばかげた質問かもしれない;それを理解しようとすると、私が答える):)ありがとう... – Ryan

+0

あなたは正確に何をしようとしていますか? – user545424

+0

この配列の '> u2'値(0-65283)を範囲(0-1023)にマップする必要があります。'> u2'は16ビットですが、この特定の配列では10ビットしか有効ではありません(リトルエンディアンでは' 00001111111111 '、ビッグエンディアンでは '1111111100000011')。 65283( '> u2')は、ビッグエンディアンでは '1100110000000000'、リトルエンディアンでは '0000000011001100'(= 204)となります。もちろん、私はむしろ6528(例えば)をバイナリ形式の文字列表現に変換するのではなく、多くの0が必要ですが、その後intに変換してください。 – Ryan

関連する問題