为了账号安全,请及时绑定邮箱和手机立即绑定

提取并连接 Numpy 数组的第 3 维

提取并连接 Numpy 数组的第 3 维

明月笑刀无情 2021-10-26 18:58:23
背景从一个计算机爱好者的视频中,我有了玩最低有效位隐写术的想法。现在,我正在尝试使用 Numpy 以图像的位格式提取和连接所有 RGB 值。最终,我只需要数组的第 7 位和第 8 位。设置我用Pillow以下方式加载图像并提取位:from PIL import Imageimport numpy as npimg = Image.open('test.png')arr = np.array(img)bits = np.unpackbits(arr, axis=2)问题bits对于 1600x1200 像素的图像,该阵列现在具有例如 (1600, 1200, 24) 的形状。我现在需要的是为每个像素提取 24 位将所有 24 位块连接成一个一维数组。仅提取第 7、8、15、16、23 和 24 位,因此仅提取每个颜色分量的最后 2 位。到目前为止的方法我试图分裂沿着第二轴的3D阵列分为3组。然后我可以遍历 1200 个列表,每个列表包含 3 个列表并提取最后 2 位,如下所示:sp = np.split(bits, 3, axis=2)for i in range(0, 1200):    for j in range(0, 3):        print(sp[j][0][i][-2:])题虽然我的上述方法有效,但我觉得必须有一个更高效的解决方案,只使用Numpy Magic®. 你知道更好的方法吗?
查看完整描述

1 回答

?
慕勒3428872

TA贡献1848条经验 获得超6个赞

这是一个XY 问题。您不需要将像素转换为二进制或使用显式方法提取任何特定位,因为这样您就必须再次将其全部拼接起来。你可以直接用按位运算做你想做的事,因为“二进制”和十进制是同一个数字的两种表示。ANDs 和SHIFTs 的组合将允许您将整数的任何部分归零,或隔离特定范围的位


例如,


>> (107 >> 3) & 7

5

因为


Decimal: 107      >> 3 = 13       & 7        = 5

Binary : 01101011 >> 3 = 00001101 & 00000111 = 00000101

           |-|                |-| 

         we want

         these 3

现在,假设您的信息是世界“你好”。您可以像这样方便地将每个字节分成四部分。


secret = b'hello'

bits = []

for byte in secret:

    for i in range(6, -1, -2):

        bits.append((byte >> i) & 3)

bits = np.array(bits)

由于每个bits元素包含两位,因此值的范围可以在 0 到 3 之间。如果您考虑二进制中的字母 'h',即 '01|10|10|00',您可以看到它的前几个值是bits如何1、2、2、0 等


为了利用 numpy 中的矢量化操作,我们应该展平我们的图像数组,我假设它的形状为 (height, width, 3)。


np.random.seed(0)

img = np.random.randint(0, 255, (1600, 1200, 3)).astype(np.uint8)

shape = img.shape

# this specific type of flattening puts the pixels in your desired order, i.e.,

# pixel (0, 0) red-green-blue, pixel (0, 1) red-green-blue, etc

flat_img = img.reshape(-1).copy()

现在嵌入很简单


length = len(bits)

flat_img[:length] = (flat_img[:length] & 252) + bits

stego_img = flat_img.reshape(shape)


查看完整回答
反对 回复 2021-10-26
  • 1 回答
  • 0 关注
  • 269 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信