python – 使用LSB方法提取OpenCV图像

免责声明:这是家庭作业的一部分,但它已经通过了.我只是在寻找未来技术诀窍的正确解决方案.

该程序的目标是使用Python OpenCV库来实现图像 – >图像隐写术(在其他图像中嵌入/提取图像).这是通过使用最低有效位(LSB)方法的两个相同大小的图像来完成的.

该程序允许用户选择用于嵌入的位数,因此使用1位时,嵌入的图像几乎检测不到人眼,而使用7位可以清楚地显示隐藏的图像.

通过从秘密图像中获取每个RGB字节的最高有效位(MSB),并将它们设置在封面图像的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)

最佳答案 njuffa是对的.在提取中,当你只嵌入1位时,你希望AND与0b00000001(1),2位与0b00000011(3),3位与0b00000111(7)等.一般来说,对于k嵌入位,你想要面具2 ** k – 1.

而且,cv2.imread()将生成像素的numpy数组.您可以将计算矢量化,而不是遍历每个像素.总而言之,这就是您的代码的样子.

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)
点赞