2016-10-29 2 views
3

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

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

и где встроена функция? Мы не знаем, как вы обнимали изображение. – furas

+0

Это выглядит некорректно: '& bitsUsed', вероятно, должно быть' & ((1 << bitsUsed) - 1) ', предполагая, что' bitsUsed' находится в [1,7], что подразумевается под вопросом. Кроме того, у вас есть 'img.item (y, x, 0)' через 'img.item (y, x, 2)', что подразумевает, что вы должны иметь 'secretImg.itemset (y, x, 0)' через 'secretImg. НИКАКИЕ гарантии (у, х, 2) '. – njuffa

+0

Возможно, это поможет (стеганография C++ для скрытия текста в изображениях): https://github.com/devkicks/HiddingDataInImages/blob/master/HiddenImageData/main.cpp#L82 – masad

ответ

2

njuffa правильно. При извлечении, когда вы ввели только 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) 
Смежные вопросы