OpenCV使用LSB方法提取图像

Posted

技术标签:

【中文标题】OpenCV使用LSB方法提取图像【英文标题】:OpenCV extracting image using LSB method 【发布时间】:2017-03-12 06:49:05 【问题描述】:

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

这个程序的目标是使用 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)

【问题讨论】:

嵌入功能在哪里?我们不知道您是如何嵌入图片的。 这看起来不正确:&amp; bitsUsed 可能应该是 &amp; ((1 &lt;&lt; bitsUsed) - 1),假设 bitsUsed 如问题所暗示的那样在 [1,7] 中。此外,您拥有img.item(y,x,0)img.item(y,x,2),这意味着您应该拥有secretImg.itemset(y,x,0)secretImg.itemset(y,x,2) 也许这会有所帮助(用于在图像中隐藏文本的 C++ 隐写术):github.com/devkicks/HiddingDataInImages/blob/master/… @masad OP 不是在寻找一些代码,而是在询问关于特定算法的特定问题。没有解释它如何解决 OP 的问题或它是如何相关的代码转储将没有用。您链接的算法甚至与OP正在研究的算法都不相同,因此他甚至无法通过研究来学习。 【参考方案1】:

njuffa 是正确的。在提取中,当您仅嵌入 1 位时,您希望与 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)

【讨论】:

以上是关于OpenCV使用LSB方法提取图像的主要内容,如果未能解决你的问题,请参考以下文章

如何用opencv提取一张图片的像素矩阵

OpenCV:并发GetSubImage以提取图像的一部分

OpenCV-Python之——图像SIFT特征提取

使用opencv获取(内边缘)轮廓像素

OpenCV中BLOB特征提取与几何形状分类

简单的图像显著性区域特征提取方法-----opencv实现LC,AC,FT