图像隐写术脚本未产生正确的结果

Image steganography script not producing correct results

我正在尝试使用 PIL 中的图像库在 python 3.7.2 中制作图像隐写术脚本。我将一个图像隐藏在另一个图像中的脚本无法正常工作,一旦生成的文件 hidden.png 再次被提取,它就会输出全黑图像或对比度较低且颜色不同的图像,具体取决于所选的位数。 (我的提取脚本已经过测试并且可以正常工作。)我通常选择 4 位,但它在 7 位时仍然无法正常工作。

这是我的隐藏脚本代码:

def hide(medium, secret_image, lsb):
    medimage = Image.open(medium).convert(mode="RGB") #open the medum
    secretimage = Image.open(secret_image).convert(mode="RGB") #open the secret image
    medimage = medimage.resize(secretimage.size) #resize the medium to be same size as secret
    acrossrow = 0 #start at first row
    downcol = 0 #start at first column
    secret = secretimage.load() #load pixels from secretimage
    med = medimage.load()
    while acrossrow < secretimage.height:
        downcol = 0 #stay first column until reach bottom row
        while downcol < secretimage.width:
            r, g, b, = secret[acrossrow,downcol] #r,g,b = the rgb of secret image pixel
            r = (r >> 8 - lsb) #shift amount of significant bits wanted to the end for hiding
            g = (g >> 8 - lsb)
            b = (b >> 8 - lsb)
            r1, g1, b1 = med[acrossrow,downcol] #more rgb values for medium
            r1 = r1 & (0b11111111 << lsb) #remove the last n amount of bits for replacing
            g1 = g1 & (0b11111111 << lsb)
            b1 = b1 & (0b11111111 << lsb)
            r1 = r1 | r #compare medium with secret, combining all 1s
            g1 = g1 | g
            b1 = b1 | g
            med[acrossrow,downcol] = (r1, g1, b1) #send new rgb values to medium
            downcol = downcol + 1 #go to next column
        acrossrow = acrossrow + 1 #go to next row
    medimage.save('hidden.png') #save modified image to new file
    medimage.show() #open and display new image

仅供参考:介质 = 介质路径,secret_image = 秘密路径,lsb 是我想从秘密图像隐藏到介质中的位数。

我已经检查了我的代码,但看不出问题所在,如果有人能帮助我,那就太好了。谢谢!

编辑:Here is a link to the full script if you want to test it or build on it. Here is the link to my test hidden.png That one uses 2 lsb Here is the link to the medium. Here is the link to the secret image.对于链接的媒体和秘密图像,我使用 4 lsb。

嗯,在检查了您添加的图像和 运行 我自己的测试之后,据我所知,您的代码运行正常。对于我自己的测试,我将你的 hide() 函数应用到 brain.png 文件,使用 sat.png 作为 "medium" 图像,并检查了生成的 hidden.png 文件你的 extract()链接代码中的函数从中生成(使用 4lsb 值)。

是的,结果中的颜色与原始颜色略有不同,但这是意料之中的,因为所使用的隐藏过程有效地将原始 (3 x 8) 的每像素 24 位减少到 12 ( 3 * 4),所以对比度之类的东西会因此受到影响,这是可以理解的。

下面是在我的图像编辑器中并排显示的图像的原始(左)和提取版本,显示了这些差异:

我认为问题可能仅仅是因为您没有完全理解这种特殊的隐写技术是如何工作的。

我已经检查了我的代码并通过将我的提取脚本从我的原始隐藏代码更改为:

def hide(medium, secret_image, lsb):
    medimage = Image.open(medium).convert(mode="RGB")
    secretimage = Image.open(secret_image).convert(mode="RGB")
    medimage = medimage.resize(secretimage.size)
    acrossrow = 0
    downcol = 0
    secret = secretimage.load()
    med = medimage.load()
    result = Image.new("RGB", medimage.size)
    r_pixels = result.load()
    while acrossrow < secretimage.height:
        downcol = 0
        while downcol < secretimage.width:
            m_r, m_g, m_b = med[acrossrow, downcol]
            s_r, s_g, s_b = secret[acrossrow, downcol]
            r = (m_r >> lsb << lsb) | (s_r >> (8 - lsb))
            g = (m_g >> lsb << lsb) | (s_g >> (8 - lsb))
            b = (m_b >> lsb << lsb) | (s_b >> (8 - lsb))
            r_pixels[acrossrow, downcol] = r, g, b
            downcol = downcol + 1
        acrossrow = acrossrow + 1
    result.save('testhid.png')
    result.show()
    result.close() 
    medimage.close()
    secretimage.close()

它现在可以完美地处理@martineau 发布的两张黄色大脑的图片。我更新后的代码的 link 是 here. 如果有人能解释为什么这行得通而我的原始代码行不通,那就太好了! 谢谢!