41

最初のバイトにエンコードされた情報が含まれているファイルがあります。Matlab では、 を使用してバイトをビットごとに読み取り、 などでvar = fread(file, 8, 'ubit1')各ビットを取得できます。var(1), var(2)

Pythonに同等のビットリーダーはありますか?

4

10 に答える 10

34

ファイルからビットを読み取ります。下位ビットが最初です。

def bits(f):
    bytes = (ord(b) for b in f.read())
    for b in bytes:
        for i in xrange(8):
            yield (b >> i) & 1

for b in bits(open('binary-file.bin', 'r')):
    print b
于 2010-04-05T08:22:42.030 に答える
27

作業できる最小単位はバイトです。ビット レベルで作業するには、ビット単位の演算子を使用する必要があります。

x = 3
#Check if the 1st bit is set:
x&1 != 0
#Returns True

#Check if the 2nd bit is set:
x&2 != 0
#Returns True

#Check if the 3rd bit is set:
x&4 != 0
#Returns False
于 2010-04-05T02:58:18.017 に答える
14

それはこのnumpyように簡単です:

Bytes = numpy.fromfile(filename, dtype = "uint8")
Bits = numpy.unpackbits(Bytes)

詳細はこちら:
http://docs.scipy.org/doc/numpy/reference/generated/numpy.fromfile.html

于 2015-05-12T17:26:13.110 に答える
12

各ビットを 1 つずつ読み取ることはできません。バイト単位で読み取る必要があります。ただし、ビットを簡単に抽出できます。

f = open("myfile", 'rb')
# read one byte
byte = f.read(1)
# convert the byte to an integer representation
byte = ord(byte)
# now convert to string of 1s and 0s
byte = bin(byte)[2:].rjust(8, '0')
# now byte contains a string with 0s and 1s
for bit in byte:
    print bit
于 2010-04-05T03:30:10.073 に答える
10

私が使用する以前の回答のいくつかに参加します。

[int(i) for i in "{0:08b}".format(byte)]

ファイルから読み取られた各バイト。0x88 バイトの例の結果は次のとおりです。

>>> [int(i) for i in "{0:08b}".format(0x88)]
[1, 0, 0, 0, 1, 0, 0, 0]

それを変数に割り当てて、最初の要求どおりに機能させることができます。「{0.08}」は、完全なバイト長を保証するためのものです

于 2017-01-03T05:15:00.420 に答える
6

ファイルから 1 バイトを読み取るには: bytestring = open(filename, 'rb').read(1). 注: ファイルはバイナリモードで開かれます。

ビットを取得するには、バイト文字列を整数に変換します: byte = bytestring[0](Python 3) またはbyte = ord(bytestring[0])(Python 2) 目的のビットを抽出します: (byte >> i) & 1:

>>> for i in range(8): (b'a'[0] >> i) & 1
... 
1
0
0
0
0
1
1
0
>>> bin(b'a'[0])
'0b1100001'
于 2016-05-12T14:16:43.793 に答える
2

バイトのi番目のビットを返す方法は2つあります。「最初のビット」は、上位ビットを参照することも、下位ビットを参照することもできます。

これは、文字列とインデックスをパラメータとして受け取り、その場所のビットの値を返す関数です。記述されているように、下位ビットを最初のビットとして扱います。最初に上位ビットが必要な場合は、示された行のコメントを外してください。

def bit_from_string(string, index):
       i, j = divmod(index, 8)

       # Uncomment this if you want the high-order bit first
       # j = 8 - j

       if ord(string[i]) & (1 << j):
              return 1
       else:
              return 0

インデックス付けは0から始まります。インデックス付けを1から始めたい場合は、を呼び出す前に関数でインデックスを調整できますdivmod

使用例:

>>> for i in range(8):
>>>       print i, bit_from_string('\x04', i)
0 0
1 0
2 1
3 0
4 0
5 0
6 0
7 0

さて、それがどのように機能するかについて:

文字列は8ビットバイトで構成されているため、最初にdivmod()を使用してインデックスを部分に分割します。

  • i:文字列内の正しいバイトのインデックス
  • j:そのバイト内の正しいビットのインデックス

この関数を使用して、ord()atの文字をstring[i]整数型に変換します。次に、(1 << j)1を左にシフトしてj番目のビットの値を計算しますj。最後に、ビット単位で使用し、そのビットが設定されているかどうかをテストします。その場合は1を返し、そうでない場合は0を返します。

于 2010-04-05T03:52:45.607 に答える
1

ビットの配列を含む Bloom_filter.bin というファイルがあり、ファイル全体を読み取り、それらのビットを配列で使用したいとします。

最初に、読み取り後にビットが格納される配列を作成し、

from bitarray import bitarray
a=bitarray(size)           #same as the number of bits in the file

open または with を使用して、ファイルを開きます。

f=open('bloom_filter.bin','rb')

次を使用して、すべてのビットを配列「a」に一度にロードします。

f.readinto(a)

'a' はすべてのビットを含む bitarray になりました

于 2015-05-15T08:34:37.483 に答える
0

これはかなり速いと思います:

import itertools
data = range(10)
format = "{:0>8b}".format
newdata = (False if n == '0' else True for n in itertools.chain.from_iterable(map(format, data)))
print(newdata) # prints tons of True and False
于 2014-11-06T19:44:19.243 に答える
0

これはよりpythonicな方法だと思います:

a = 140
binary = format(a, 'b')

このブロックの結果は次のとおりです。

'10001100'

イメージのビット プレーンを取得する必要があり、この関数を使用して次のブロックを記述しました。

def img2bitmap(img: np.ndarray) -> list:
    if img.dtype != np.uint8 or img.ndim > 2:
        raise ValueError("Image is not uint8 or gray")
    bit_mat = [np.zeros(img.shape, dtype=np.uint8) for _ in range(8)]
    for row_number in range(img.shape[0]):
        for column_number in range(img.shape[1]):
            binary = format(img[row_number][column_number], 'b')
            for idx, bit in enumerate("".join(reversed(binary))[:]):
                bit_mat[idx][row_number, column_number] = 2 ** idx if int(bit) == 1 else 0
    return bit_mat

また、このブロックによって、抽出されたビット プレーンからプリミティブ イメージを作成することができました。

img = cv2.imread('test.jpg', cv2.IMREAD_GRAYSCALE)
out = img2bitmap(img)
original_image = np.zeros(img.shape, dtype=np.uint8)
for i in range(original_image.shape[0]):
    for j in range(original_image.shape[1]):
        for data in range(8):
            x = np.array([original_image[i, j]], dtype=np.uint8)
            data = np.array([data], dtype=np.uint8)
            flag = np.array([0 if out[data[0]][i, j] == 0 else 1], dtype=np.uint8)
            mask = flag << data[0]
            x[0] = (x[0] & ~mask) | ((flag[0] << data[0]) & mask)
            original_image[i, j] = x[0]
于 2022-03-05T00:55:42.477 に答える