OpenCV извлекает изображение методом LSB

Отказ от ответственности: это было частью домашнего задания, однако, оно уже было передано. Я просто ищу правильное решение для будущего ноу-хау.

Целью этой программы было использование библиотеки Python OpenCV для реализации изображения -> стеганография изображения (встраивание / извлечение изображений внутри других изображений). Это делается с двумя изображениями одинакового размера с использованием метода младшего значащего бита (LSB).

Программа позволяет пользователю выбирать количество битов, используемых для встраивания, поэтому при использовании 1 бита внедренное изображение почти не обнаруживается человеческим глазом, а с 7 вы можете четко разглядеть скрытое изображение.

Я правильно реализовал встраивание, просто взяв старшие биты (MSB) каждого байта RGB из секретного изображения и установив их в местах LSB изображения обложки.

Моя проблема заключается в извлечении секретного изображения после его встраивания. После запуска кода изображение, с которым я остаюсь, кажется только его синим представлением. Я не уверен, где я ошибся, но у меня есть ощущение, что это как-то связано с моей техникой манипулирования битами или использованием библиотеки OpenCV. Любая помощь с благодарностью, заранее спасибо!

Код для извлечения:

import cv2
import numpy
def extract(img1, bitsUsed):
    print "Extracting..."
    # Import image & get dimensions
    img = cv2.imread(img1)
    h = img.shape[0]
    w = img.shape[1]

    # Create new image to extract secret image
    # Same dimensions, and rgb channel
    secretImg = numpy.zeros((h,w,3), numpy.uint8)

    x, y = 0, 0
    # Loop thru each pixel
    while x < w:
            while y < h:
                    # Grab the LSB (based on bitsUsed from embedding)
                    lsb_B = img.item(y,x,0) & bitsUsed
                    lsb_G = img.item(y,x,1) & bitsUsed
                    lsb_R = img.item(y,x,2) & bitsUsed
                    # Place those bits into MSB positions on new img
                    secretImg.itemset((y,x,0), lsb_B << (8 - bitsUsed))
                    secretImg.itemset((y,x,0), lsb_G << (8 - bitsUsed))
                    secretImg.itemset((y,x,0), lsb_R << (8 - bitsUsed))
                    y += 1
            y = 0
            x += 1

    cv2.imwrite("extractedImg.png", secretImg)

1 ответ

Решение

Нюффа это правильно. При извлечении, когда вы вставили только 1 бит, вы хотите использовать И с 0b00000001 (1), для 2 бит с 0b00000011 (3), для 3 бит с 0b00000111 (7) и т. Д. Обычно для k встроенные биты, вы хотите маску 2**k - 1,

Более того, cv2.imread() сгенерирует пустой массив пикселей. Вместо прохождения каждого пикселя вы можете векторизовать свои вычисления. В общем, именно так может выглядеть ваш код.

import cv2

def embed(cover_file, secret_file, k):
    cover = cv2.imread(cover_file)
    secret = cv2.imread(secret_file)

    mask = 256 - 2**k
    stego = (cover & mask) | (secret >> (8 - k))
    cv2.imwrite('stego.png', stego)

def extract(stego_file, k):
    stego = cv2.imread(stego_file)

    mask = 2**k - 1
    output = (stego & mask) << (8 - k)
    cv2.imwrite('extracted.png', output)
Другие вопросы по тегам