gpt4 book ai didi

python - 如何使用 LSB 替换将一张图像隐藏到另一张图像中?

转载 作者:行者123 更新时间:2023-12-02 17:42:56 27 4
gpt4 key购买 nike

我正在尝试实现一种基本的速记技术,其中我用消息图像的 MSB 替换载体图像的 LSB。 LSB 可以属于任何 RGB channel 。

我的方法非常幼稚,因为我正在循环 message_matrix 并将其特定 RGB channel 的 MSB 存储在 carrier_matrix 的相应 LSB 中。由于图像大小不超过 1024 * 1024,因此执行此操作的时间复杂度为 O(n^2),但由于我使用的是 python,因此与 Java 相比,所花费的时间非常高。

可以以更优化的方式执行相同的操作吗?

def hide_using_bpcs(self, carrier_path, message_path, index, color_index):
carrier_matrix = self.image_to_matrix(carrier_path)
message_matrix = self.image_to_matrix(message_path) #use np.zeros

for row_index, row in enumerate(message_matrix):
for pixel_index, pixel in enumerate(row):
color = message_matrix[row_index][pixel_index][color_index]
msb = (color & 0xff) >> 7
carrier_pixel = carrier_matrix[
row_index][pixel_index][color_index]
carrier_matrix[row_index][pixel_index][
color_index] = self.set_bit(carrier_pixel, index, msb)

stegano_image = self.matrix_to_image(carrier_matrix)
return stegano_image

现在,为了显示一个特定的位平面,比如说(红色 0),我将绿色和蓝色平面的所有值设置为 0,并仅保留图像中红色的 LSB(或 0 位)的值。我已经完成了一些使用 openCV 完成的实现,例如 [b,g,r = cv2.split(img)] 但这只是将图像拆分为 3 个 channel 。我想要的是通过保留相应位置的值来将特定 channel (让我们说红色)进一步分成 8 个变化。
    def display_bit_plane(self, path, color_index, color_bit):
matrix = self.image_to_matrix(path)
matrix = matrix.astype(int)
result_matrix = self.image_to_matrix(path)
mask = 1 << color_bit

for row_index, row in enumerate(matrix):
for pixel_index, pixel in enumerate(row):
for iterator in range(0, 3):
result_matrix[row_index][pixel_index][iterator] = 0
color = matrix[row_index][pixel_index][color_index]
result_matrix[row_index][pixel_index][color_index] = self.set_bit(0, 7, ((color & mask) != 0))

stegano_image = self.matrix_to_image(result_matrix)
return stegano_image

我正在使用 NumPy 数组来执行所有计算。然而,以通常的方式迭代它是非常昂贵的。请对以上两个功能进行一些优化,使这些操作可以在不到 1 秒的时间内完成。

编辑 1:

我已经优化了检索位平面的第二个功能。如果可以进一步简化,请告诉。 color_index 将 R、G、B 分别表示为 0、1、2,color_bit 是从 0-7 的位位置。
def display_bit_plane_optimised(self, path, color_index, color_bit): 
message_matrix = self.image_to_matrix(path)
change_index = [0, 1, 2]
change_index.remove(color_index)
message_matrix[:, :, change_index] = 0
mask = 1 << color_bit
message_matrix = message_matrix & mask
message_matrix[message_matrix == 1] = 1 << 7
stegano_image = self.matrix_to_image(message_matrix)
return stegano_image

最佳答案

任何适用于整个数组的东西都可以被矢量化。如果您只想对数组的一部分应用操作,请将其切片。

我提供了完整的代码,所以不要对 image_to_matrix() 做出假设和 matrix_to_image()方法。从那里拿走它。

否则我保持你的逻辑完整,但如果你只是打算在 LSB 中嵌入 secret ,你可以放弃 pixel_bit ,将其值设置为零并简化由此产生的任何常数。例如,在 embed()你会得到mask = 0xfe , 而任何位移 0 都是无关紧要的。

import numpy as np
from PIL import Image

class Steganography:
def embed(self, cover_file, secret_file, color_plane, pixel_bit):
cover_array = self.image_to_matrix(cover_file)
secret_array = self.image_to_matrix(secret_file)
# every bit except the one at `pixel_bit` position is 1
mask = 0xff ^ (1 << pixel_bit)
# shift the MSB of the secret to the `pixel_bit` position
secret_bits = ((secret_array[...,color_plane] >> 7) << pixel_bit)
height, width, _ = secret_array.shape
cover_plane = (cover_array[:height,:width,color_plane] & mask) + secret_bits
cover_array[:height,:width,color_plane] = cover_plane
stego_image = self.matrix_to_image(cover_array)
return stego_image

def extract(self, stego_file, color_plane, pixel_bit):
stego_array = self.image_to_matrix(stego_file)
change_index = [0, 1, 2]
change_index.remove(color_plane)
stego_array[...,change_index] = 0
stego_array = ((stego_array >> pixel_bit) & 0x01) << 7
exposed_secret = self.matrix_to_image(stego_array)
return exposed_secret

def image_to_matrix(self, file_path):
return np.array(Image.open(file_path))

def matrix_to_image(self, array):
return Image.fromarray(array)

当我运行它时,它会在一秒钟内完成。
plane = 0
bit = 1

cover_file = "cover.jpg"
secret_file = "secret.jpg"

stego_file = "stego.png"
extracted_file = "extracted.png"

S = Steganography()
S.embed(cover_file, secret_file, plane, bit).save(stego_file)
S.extract(stego_file, plane, bit).save(extracted_file)

备注

您的 display_bit_plane_optimised()进行了合理优化,但如果 color_bit 则存在错误不是0。这条线
message_matrix = message_matrix & mask

每隔一位清零,但除非 color_bit是 0,值将是 2 的其他幂。所以当你来到
message_matrix[message_matrix == 1] = 1 << 7

没有像素被修改。如果您想保持自己的方式,则必须将最后一行更改为
message_matrix[message_matrix != 0] = 1 << 7

我的方法是简单地将嵌入位带到 LSB 位置,每隔一个位清零,然后将其移到 MSB 位置而没有条件。

关于python - 如何使用 LSB 替换将一张图像隐藏到另一张图像中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42156400/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com