Значение пикселя, сохраненное в изображении, изменяется автоматически Если изображение снова открывается в другой функции - PullRequest
0 голосов
/ 18 января 2019

Функция данных PreProcess возвращает список значений данных ASCII.

def preprocess_data(data):
data_list = []
for ch in data:
    data_list.append(list(format(ord(ch), '08b')))
return data_list

Здесь я пытаюсь реализовать алгоритм LSB для стеганографии изображения. Он открывает изображение temp.JPG и затем устанавливает бит LSB равным 1, если для данных установлено значение «1», для бит 0, если для данных установлено значение «0». Зашифрованное изображение хранится в enc_img.JPG. В качестве стоп-слова я использую '11111111'.

def encode():
data = "This is a data"
img = Image.open("temp.JPG")
data = preprocess_data(data)
data.append(list('11111111'))
print(data)
i=0
j=0
enc_img = img.copy()
enc_img.save("OUT.JPG")
height, width = enc_img.size
pixels = enc_img.load()
f = 0
for h in range(height):
    for w in range(width):
        pixel = enc_img.getpixel((h, w))
        pixel = list(pixel)
        newpixel = []
        # retrieveing the pixel at (h,w)
        for k in range(3):
            #if LSB is 1 and data value is 0 updating the pixel
            if pixels[h,w][k]&1 and data[i][j] == '0':
                newpixel.append(pixel[k] ^ 1)
            else:
                # if LSB is 0 and data value is 1 updating the pixel
                if (pixels[h,w][k]&1) == 0 and data[i][j] == '1':
                    newpixel.append(pixel[k] | 1)
                else:
                    newpixel.append(pixel[k])
            j = (j + 1) % 8
            if j == 0:
                i += 1
                # if whole data list encrypted then break
                if i == len(data):
                    print("Saved")
                    enc_img.save('temp2.JPG')
                    f=1
                    break
        pixels[h, w] = tuple(newpixel)
        if f:
            break
    if f:
        break
print("Encoding done!!")

Здесь я декодирую зашифрованное изображение, просматривая полную картину. Если я найду стоп-слово, я верну данные.

def decode():
img = Image.open("temp2.JPG")
img2 = Image.open("temp.JPG")
height, width = img.size
data = ""
k = 0
l=1
j=0
st = ""
pixels = img.load()
pixels2 = img2.load()
for h in range(height):
    for w in range(width):
        print(pixels[h, w])
        print(pixels2[h, w])
        for k in range(3):
            st += str(pixels[h, w][k]&1)
            j = (j+1)%8
            if j==0:
                print(str(l) + st)
                if st == "11111111":
                    return data
                l += 1
                st = ""
                break

def main():
    encode()
    decode()
if __name__ == '__main__':
    main()

Например, в позиции (0,0) у меня есть значение (7,54,84), а значение данных равно ['0', '1', '0'], тогда enc_img имеет (6,55,84) ). Если я открою enc_img в функции декодирования, то значение пикселя в позиции (0,0) изменится на (5,54,86). Я не могу понять это ненормальное поведение. Спасибо!

1 Ответ

0 голосов
/ 03 февраля 2019

Это потому, что вы используете формат изображения с потерями. Когда вы сохраняете изображение в формате jpg, некоторые данные теряются (изображение сжимается). Измените тип изображения, например, на png или bmp (или другой формат без потерь), и все будет работать.

Вы не хотите (обычно) использовать стеганографию LSB с изображениями JPG.

...