简单的 LSB图像水印算法 python版本

LSB Least Significant Bit 最低有效位嵌入,这里就不赘述了。很多参考,原理一搜就出来了。

下面是相应的代码
首先,编写encode 和decode 代码,使用位操作

def LSB_encode(cover, m, k):
    m = np.array(m, dtype = np.uint8)
    cover = np.array(cover, dtype = np.uint8)

    k = 2**k -1
    mask1 = 255-k
    mask2 = k
    cover = np.bitwise_and(cover, mask1)
    m = np.bitwise_and(m, mask2)
    res =  np.bitwise_or(cover,m)
    return res
    
def LSB_decode(cover, k):
    cover = np.array(cover, dtype = np.uint8)
    mask1 = 2**k -1
    
    m = np.bitwise_and(cover, mask1)
    
    res = np.zeros(k, dtype = np.uint8)
    m = str(bin(m))
    m = m[2:].zfill(k)
    for i in range(k):     
        res[i] = int(m[i])
    return res

然后是嵌入和提取水印的代码:

def LSB_embed(im, wm, k):
    xsize,ysize = im.shape
    num = xsize * ysize
    wm = wm.flatten() // 255
    im_array = np.array(im)
    im_array = im_array.reshape(num)

    for i in range(num):
        m = int("".join(list(map(str, wm[i:i+k]))),2)
        im_array[i] =  LSB_encode(im_array[i], m, k)
        
    im_wm = im_array.reshape(xsize,ysize)    
    return im_wm
    
def LSB_extract(im, k):
    xsize,ysize = im.shape
    num = xsize * ysize
    
    im_array = np.array(im)
    im_array = im_array.reshape(num)
    wm_ex = np.zeros(num*k, dtype= np.uint8)
    
    for i in range(num):
        m = LSB_decode(im_array[i], k)
        wm_ex[i:i+k] = m
    wm_ex = wm_ex.reshape(xsize,ysize,-1)
    wm_ex = wm_ex.squeeze()
    return wm_ex
    

最后是主函数,这里为了方便展示效果,将 嵌入的最低位数 K设为1。如果k不是1,嵌入和提取函数还要有稍微的改动。

import numpy as np
from PIL import Image
from skimage import data
import matplotlib.pyplot as plt



wm = Image.open('watermark.png')
wm = np.array(wm)
im = data.camera()


k = 1
# wm = np.random.randint(0,2, (im.shape[0],im.shape[1],k), dtype = np.uint8).squeeze()

im_wm = LSB_embed(im, wm, k)
wm_ex = LSB_extract(im_wm, k)


fig, (ax_wm, ax_im, ax_im_wm, ax_wm_ex)=plt.subplots(nrows = 1,ncols = 4, figsize = [20,20])
ax_wm.imshow(wm, cmap = plt.cm.gray)
ax_wm.set_xlabel('wm')
ax_im.imshow(im, cmap = plt.cm.gray)
ax_im.set_xlabel('im')
ax_im_wm.imshow(im_wm, cmap = plt.cm.gray)
ax_im_wm.set_xlabel('im_wm')
ax_wm_ex.imshow(wm_ex, cmap = plt.cm.gray)
ax_wm_ex.set_xlabel('wm_ex')

下面是效果图:
在这里插入图片描述
另外,这里给出为彩色图像加 K=3 随机信息的代码:

### color LSB watermark
k = 3
im = Image.open("lena.png")
im = np.array(im)
r,g,b = im[:,:,0],im[:,:,1],im[:,:,2]

np.random.seed(0)
wm = np.random.randint(0,2, im.shape[0]*im.shape[1]*k, dtype = np.uint8)
r_wm = LSB_embed(r, wm, k)

np.random.seed(1)
wm = np.random.randint(0,2, im.shape[0]*im.shape[1]*k, dtype = np.uint8)
g_wm = LSB_embed(g, wm, k)

np.random.seed(2)
wm = np.random.randint(0,2, im.shape[0]*im.shape[1]*k, dtype = np.uint8)
b_wm = LSB_embed(b, wm, k)

im_wm = np.dstack((r_wm, g_wm, b_wm))

fig, ( ax_im, ax_im_wm, )=plt.subplots(nrows = 1,ncols = 2, figsize = [20,20])
ax_im.imshow(im, cmap = plt.cm.gray)
ax_im.set_xlabel('im')
ax_im_wm.imshow(im_wm, cmap = plt.cm.gray)
ax_im_wm.set_xlabel('im_wm')

运行结果如下所示:
在这里插入图片描述

  • 0
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
LSB(Least Significant Bit)图像水印法是一种基于比特替换的图像水印技术,可以将一张水印图片嵌入到原始图像中,以达到保护版权、鉴别真伪等目的。下面是一个简单LSB 图像水印法的 Python 实现。 首先,我们需要安装 Pillow 库,它是 Python 的一个图像处理库,可以方便地进行图像读取、处理和保存等操作。在命令行中输入以下命令安装 Pillow: ``` pip install Pillow ``` 然后,我们定义一个函数 `encode_lsb()`,用于将水印图像嵌入到原始图像中。其中,参数 `src_path` 和 `watermark_path` 分别表示原始图像水印图像的路径,参数 `dst_path` 表示输出的带水印图像的路径: ```python from PIL import Image def encode_lsb(src_path, watermark_path, dst_path): # 加载原始图像水印图像 src_img = Image.open(src_path).convert('RGBA') watermark_img = Image.open(watermark_path).convert('RGBA') # 将水印图像缩放为原始图像的大小 watermark_img = watermark_img.resize(src_img.size, Image.ANTIALIAS) # 将水印图像转换为灰度图像,并获取它的像素值矩阵 watermark_data = watermark_img.convert('L').getdata() # 获取原始图像的像素值矩阵 src_data = list(src_img.getdata()) # 将水印图像的像素值嵌入到原始图像中 for i in range(len(src_data)): r, g, b, a = src_data[i] if i < len(watermark_data): watermark_bit = watermark_data[i] & 1 # 获取水印像素的最低位 if watermark_bit == 1: r |= 1 # 将原始像素的红色通道的最低位替换为1 else: r &= ~1 # 将原始像素的红色通道的最低位替换为0 src_data[i] = (r, g, b, a) # 保存带水印图像 dst_img = Image.new('RGBA', src_img.size) dst_img.putdata(src_data) dst_img.save(dst_path) ``` 接下来,我们定义一个函数 `decode_lsb()`,用于从带水印图像中提取出水印图像。其中,参数 `src_path` 表示带水印图像的路径,参数 `dst_path` 表示输出的水印图像的路径: ```python def decode_lsb(src_path, dst_path): # 加载带水印图像 src_img = Image.open(src_path).convert('RGBA') # 获取带水印图像的像素值矩阵 src_data = list(src_img.getdata()) # 从带水印图像中提取水印图像的像素值 watermark_data = [] for i in range(len(src_data)): r, g, b, a = src_data[i] watermark_bit = r & 1 # 获取原始像素的红色通道的最低位 watermark_data.append(watermark_bit * 255) # 将最低位转换为像素值 # 保存水印图像 watermark_img = Image.new('L', src_img.size) watermark_img.putdata(watermark_data) watermark_img.save(dst_path) ``` 最后,我们可以调用这两个函数来进行 LSB 图像水印的嵌入和提取操作: ```python # 将水印图像嵌入到原始图像中 encode_lsb('原始图像路径', '水印图像路径', '输出图像路径') # 从带水印图像中提取水印图像 decode_lsb('带水印图像路径', '输出图像路径') ``` 需要注意的是,LSB 图像水印法是一种比较简单图像水印技术,容易被攻击和破解。在实际应用中,需要考虑到安全性和鲁棒性等因素,并结合其他技术进行综合保护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值