Как я могу положить список в 2d массив с известным размером 283 * 283, используя Python - PullRequest
0 голосов
/ 20 октября 2019

Я хочу спрятать (невидимый водяной знак) строку в изображение (283 * 283), используя алгоритм LSB (наименее значимый бит). пользователь дает скрытое сообщение (строку), затем я помещаю в список код ascii всех символов (основание 2), теперь я хочу сделать этот список двумерным массивом того же размера, что и мое изображение, тогда я могу использовать '&' и '|'операторы.

import cv2 as cv

#read image:

img=cv.imread('C:/Users/pc/Desktop/cameraman.jpg',0)
cv.imshow("ax bedoon ramz",img)
cv.waitKey()

#make least significant bit of each pixel 0 :

img_r=img&0b11111110
img_w=img_r.copy()

#take message and make sure it can hide in 283*283 image :

while True:
    txt=input('chi maikhay ghayem koni ? (max = 10000 character) : ')
    if len(txt)>10000:
        print('out of range characters ! ! ! ')
    else :
        break

#put characters ascii code in list :

ch_ascii_base2 = [bin(ord(i))[2:] for i in txt]

result=[]
for ch in ch_ascii_base2:
    for val in ch:
        result.append(bin(int(val))[2:])

1 Ответ

0 голосов
/ 20 октября 2019

Нет смысла обнулять все LSB всех пикселей, потому что, если ваш секрет намного меньше размера вашего изображения, вы изменили ~ 50% оставшихся пикселей без причины.

Я бы просто получил битовый поток сообщения, сгладил изображение и затем скрыл ваше сообщение в фрагменте этого массива, который соответствует сообщению. Затем измените его обратно на 2D.

string = 'Hello world'

# Getting the bits from each character with bitwise operations is better
# than using intermediate strings with `bin` or string formats
for byte in map(ord, string):
    bits.extend((byte >> i) & 1 for i in range(7, -1, -1))

flat = img.flatten()
flat[:len(bits)] = (flat[:len(bits)] & 0xfe) | bits
stego = flat.reshape(img.shape)

Если изображение RGB, то порядок пикселей равен (0, 0, R), (0, 0, G), (0, 0,B), (0, 1, R) и т. Д. Если вы хотите сначала встроить свой секрет, скажем, только в синий канал, извлеките эту цветовую плоскость, вставьте столько битов, сколько она может вписать в описанный выше процесс, изатем перейдите на другой канал. Это немного более запутанно, но не очень сложно.

Если вы настаиваете на преобразовании потока битов в двумерный массив того же размера, что и ваше изображение, просто посчитайте, сколько пикселей у вашего изображения, сколько битов у вас есть, идобавьте столько единиц или 0 к вашему потоку битов. Затем используйте np.reshape(). Опять же, если в результате получается трехмерный массив, вы должны помнить об окончательном порядке битов.

В общем, если вам не нужно внедрять свой секрет в конкретные плоскости, используйтеметод, который я предложил. Он очень короткий и понятный и не требует каких-либо посторонних вычислений или модификаций вашего изображения.

...