Это XY проблема .Вам не нужно преобразовывать пиксели в двоичные или извлекать какие-либо конкретные биты с помощью явных методов, потому что тогда вам придется снова сшивать все заново.Вы можете напрямую делать то, что хотите, с помощью побитовых операций , потому что «двоичное» и десятичное - это два представления одного и того же числа.Комбинация AND
s и SHIFT
s позволит вам обнулить любую часть целого числа или выделить определенный диапазон битов
Например,
>> (107 >> 3) & 7
5
Потому что
Decimal: 107 >> 3 = 13 & 7 = 5
Binary : 01101011 >> 3 = 00001101 & 00000111 = 00000101
|-| |-|
we want
these 3
Теперь, допустим, ваше сообщение - это мир "привет".Вы можете удобно разделить каждый байт на четыре части следующим образом.
secret = b'hello'
bits = []
for byte in secret:
for i in range(6, -1, -2):
bits.append((byte >> i) & 3)
bits = np.array(bits)
Поскольку каждый элемент bits
содержит два бита, значения могут находиться в диапазоне от 0 до 3. Если вы думаете о букве 'h'в двоичном формате, который равен '01 | 10 | 10 | 00 ', вы можете видеть, как первые несколько значений bits
равны 1, 2, 2, 0 и т. д.
Чтобы воспользоваться векторизованными операциямив numpy, мы должны сгладить наш массив изображений, который, как я полагаю, имеет форму (высота, ширина, 3).
np.random.seed(0)
img = np.random.randint(0, 255, (1600, 1200, 3)).astype(np.uint8)
shape = img.shape
# this specific type of flattening puts the pixels in your desired order, i.e.,
# pixel (0, 0) red-green-blue, pixel (0, 1) red-green-blue, etc
flat_img = img.reshape(-1).copy()
А теперь встраивание просто
length = len(bits)
flat_img[:length] = (flat_img[:length] & 252) + bits
stego_img = flat_img.reshape(shape)