LSB水印嵌入与提取-灰度图像_Python Version

文章目录

  • 摘要
  • 1. 方法
    • 1.1 步骤
    • 1.2 代码
    • 1.3 embed_bit=3(低3位嵌入) 实验现象
    • 1.3 实验现象分析
    • 1.4 所有实验现象
  • 2. 更新-彩色水印嵌入与提取
  • 参考资料

LSB水印嵌入与提取-灰度图像_Python Version_第1张图片

摘要

数字水印技术是一种保护图像版权的方式。LSB(Least Significant Bits, 最低有效位)技术是空域水印嵌入的一种方式。本文以灰度图像为对象,使用Python实现了任意长度位平面的水印嵌入方式,并且可以提取出水印对应的灰度图像。

1. 方法

1.1 步骤

  1. 读取图像(background、watermark)
  2. 对读取的图像进行嵌入
    2.1 划分对应的位平面
    2.2 将background的低位位平面替换为watermark的高位位平面
    2.3 合成图像(synthesis) ,实现嵌入
  3. 进行提取并绘制结果

本实验选择的嵌入位数是3

1.2 代码

喜欢的东西都在码里,可以不用本地配置环境,使用百度的飞浆平台进行在线运行。
开源这个代码不求赞,只求你们可以注册帮我拿点算力,或者fork一下项目,我真的很需要算力,所以希望我劝各位年轻人,要讲武德,耗子尾汁,不要白嫖。好卑微的博主呜呜呜。下面第一个Link给的算力多,注册之后点第二个link可以在线运行

百度飞浆邀请注册地址

该项目在线运行地址

import numpy as np
import matplotlib.pyplot as plt
import cv2


class LSB_Embed():
    def __init__(self):
        pass

    @staticmethod
    def get_bitPlane(img):
        """
        获取灰度图像的8个位平面
        :param img: 灰度图像
        :return: 8个位平面的矩阵
        """
        h, w = img.shape

        flag = 0b00000001
        bitPlane = np.zeros(shape=(h, w, 8))
        for i in range(bitPlane.shape[-1]):
            bitplane = img & flag  # 获取图像的某一位,从最后一位开始处理
            bitplane[bitplane != 0] = 1  # 阈值处理 非0即1
            bitPlane[..., i] = bitplane  # 处理后的数据载入到某个位平面
            flag <<= 1  # 获取下一个位的信息
        return bitPlane.astype(np.uint8)

    @staticmethod
    def lsb_embed(background, watermark, embed_bit=3):
        """
        在background的低三位进行嵌入水印,具体为将watermark的高三位信息替换掉background的低三位信息
        :param background: 背景图像(灰度)
        :param watermark: 水印图像(灰度)
        :return: 嵌入水印的图像
        """
        # 1. 判断是否满足可嵌入的条件
        w_h, w_w = watermark.shape
        b_h, b_w = background.shape
        assert w_w < b_w and w_h < b_h, "请保证watermark尺寸小于background尺寸\r\n当前尺寸watermark:{}, background:{}".format(
            watermark.shape, background.shape)

        # 2. 获取位平面
        bitPlane_background = lsb.get_bitPlane(background)  # 获取的平面顺序是从低位到高位的 0 1 2 3 4 5 6 7
        bitPlane_watermark = lsb.get_bitPlane(watermark)

        # 3. 在位平面嵌入信息
        for i in range(embed_bit):
            # 信息主要集中在高位,此处将watermark的高三位信息 放置在 background低三位信息中
            bitPlane_background[0:w_h, 0:w_w, i] = bitPlane_watermark[0:w_h, 0:w_w, (8 - embed_bit) + i]

        # 4. 得到watermark_img 水印嵌入图像
        synthesis = np.zeros_like(background)
        for i in range(8):
            synthesis += bitPlane_background[..., i] * np.power(2, i)
        return synthesis.astype(np.uint8)

    @staticmethod
    def lsb_extract(synthesis, embed_bit=3):
        bitPlane_synthesis = lsb.get_bitPlane(synthesis)
        extract_watermark = np.zeros_like(synthesis)
        extract_background = np.zeros_like(synthesis)
        for i in range(8):
            if i < embed_bit:
                extract_watermark += bitPlane_synthesis[..., i] * np.power(2, (8 - embed_bit) + i)
            else:
                extract_background += bitPlane_synthesis[..., i] * np.power(2, i)
        return extract_watermark.astype(np.uint8), extract_background.astype(np.uint8)


if __name__ == '__main__':
    root = ".."
    lsb = LSB_Embed()
    # 1. 获取背景和水印
    background = cv2.imread(r"{}/datasets/background/460.pgm".format(root), cv2.IMREAD_GRAYSCALE)
    watermark = cv2.imread(r"{}/datasets/watermark/swjtu2.png".format(root), cv2.IMREAD_GRAYSCALE)
    background_backup = background.copy()
    watermark_backup = watermark.copy()
    # 2. 进行水印嵌入
    embed_bit = 2
    synthesis = lsb.lsb_embed(background, watermark, embed_bit)
    # 3. 进行水印提取
    extract_watermark, extract_background = lsb.lsb_extract(synthesis, embed_bit)
    imgs = [background_backup, watermark_backup, synthesis, extract_watermark, extract_background]
    title = ["background", "watermark", "synthesis", "extract_watermark", "extract_background"]
    for i in range(len(imgs)):
        plt.subplot(2, 3, i + 1)
        plt.imshow(imgs[i], cmap="gray")
        plt.axis("off")
        plt.title(title[i])
    plt.show()

1.3 embed_bit=3(低3位嵌入) 实验现象

LSB水印嵌入与提取-灰度图像_Python Version_第2张图片

1.3 实验现象分析

  1. background和synthesis不仔细看是分不出来区别的,但是仔细看,能看出来swjtu的logo有些痕迹,如果减少嵌入位数,就无法看出痕迹了。
  2. extract_watermark的颜色和watermark的颜色不一致。实际测试,这应该是python绘图显示的原因,当我把水印区域的数据单独截取出来进行绘制。效果如下:
    LSB水印嵌入与提取-灰度图像_Python Version_第3张图片
    几乎与watermark一致,看不出来区别。
  3. extract_watermark水印的其他部分是因为没有做处理导致的。在进行提取的时候,没有给予提取算法的水印尺寸这个先验信息,算法不知道哪里是水印边界,因此只有水印部分可被算法正常提取,算法将其余部分与水印部分一视同仁进行提取,因此产生了像马赛克一样的图像。

1.4 所有实验现象

  1. embed_bit = 1
    LSB水印嵌入与提取-灰度图像_Python Version_第4张图片

  2. embed_bit = 2
    LSB水印嵌入与提取-灰度图像_Python Version_第5张图片

  3. embed_bit = 3
    LSB水印嵌入与提取-灰度图像_Python Version_第6张图片

  4. embed_bit = 4
    LSB水印嵌入与提取-灰度图像_Python Version_第7张图片

  5. embed_bit = 5
    LSB水印嵌入与提取-灰度图像_Python Version_第8张图片

  6. embed_bit = 6
    LSB水印嵌入与提取-灰度图像_Python Version_第9张图片

  7. embed_bit = 7
    LSB水印嵌入与提取-灰度图像_Python Version_第10张图片

  8. embed_bit = 8
    LSB水印嵌入与提取-灰度图像_Python Version_第11张图片

2. 更新-彩色水印嵌入与提取

该文章是对灰度图进行LSB进行操作,只需进行一些微微修改,即可实现图像的嵌入与提取,点击查看link。

参考资料

[1]. github
[2]. 最低有效位LSB图像水印法[1.5x]

你可能感兴趣的:(数字水印,python,数字水印,图像处理,信息隐藏)