Python+OpenCV 实现图像位平面分层进行图像信息隐藏

引言

闲言:这篇博客回归了传统图像处理领域,主要是在研究生的数字图像处理课程上接触到了新的知识--图像位平面,觉得还挺有意思的,可以用来做信息隐藏,索性记录一下。因为拖延的缘故,到学期末才赶出来一篇,后续可能还会有一篇消除图像摩尔纹的trick介绍(如果效果好的话)。  本文的主题是介绍图像位平面相关知识,并依据不同位平面包含信息量的多寡设计了一种图像信息隐藏的算法,实际就是位平面的叠加,可以适用于图片加水印等场景。

图像位平面

首先对图像的位平面进行介绍,众所周知,图像在计算机中存储方式为二维矩阵,矩阵的每一个元素都代表对应位置处像素点的亮度值,通常用uint8来表示,取值范围为0~255。换而言之,每个像素点都是一个8位二进制数,那么如果我们将每个像素点的一位抽取出来就可构造一个对应原图大小的为片面,其元素取值变为了0~1。举例而言,假设有一2*2的图像,其灰度值为: <math xmlns="http://www.w3.org/1998/Math/MathML"> [ [ 1 , 2 ] , [ 3 , 4 ] ] [[1,2],[3,4]] </math>[[1,2],[3,4]] 那么其最低位位平面就为: <math xmlns="http://www.w3.org/1998/Math/MathML"> [ [ 1 , 0 ] , [ 1 , 0 ] ] [[1,0],[1,0]] </math>[[1,0],[1,0]]

值得注意的是,不同位片面的取值范围虽然相同,但其所包含的信息量是不同的(或者说权重),这是因为在构成图像时,它们要乘以对应二进制位数的权重,而位数越高从0变换至1或者从1变化至0给图像带来的影响越剧烈,位数越高保留的图像信息越整体,反之则越细节。对比如下:

那么利用这一性质,我们就可以把用隐藏图片的最高位平面替换载体图片的最低位片面来达到隐藏信息,或者给图片加水印的目的。

代码

代码上实现还是比较简单的,通过与运算提取出待隐藏图片的最高位平面,将其信息移动到要插入的位平面;然后去除载体图片对应的位平面,并进行替换即完成了隐藏部分。复原部分就只是前一阶段的逆过程,整体如下所示

python 复制代码
import cv2
import warnings
import numpy as np
import matplotlib.pyplot as plt

def InfoHidden(carry_img,info_img,bit_plane):
    """
    carry_img: 作为载体的图片
    info_img: 作为隐藏信息的图片
    bit_plane: 要进行信息替换的平面
    """
    assert bit_plane in range(0,8),"Invaied BitPlane"
    if carry_img.shape!=info_img.shape:
        warnings.warn("shape of the two images don't match")
        carry_img=cv2.resize(carry_img,(info_img.shape[1],info_img.shape[0]))
    # 抽取info_img信息量最大平面
    info_img=np.bitwise_and(info_img,np.left_shift(1,7))
    # 转为二进制
    info_img_bit=np.right_shift(info_img,(7-bit_plane))
    # 构造carry_img的蒙版
    mask=np.bitwise_not(np.left_shift(1,bit_plane))
    hidden_img=info_img_bit+np.bitwise_and(carry_img,mask)
    return  hidden_img

def InfoExtrac(hidden_img,bit_plane):
    # 提取位平面
    recoverd_img = np.bitwise_and(hidden_img, np.left_shift(1,bit_plane))
    # 提升到最高位恢复信息
    recoverd_img=np.left_shift(recoverd_img,(7-bit_plane))
    return recoverd_img
img_path1=r"D:\temp\pic1.jpg"
img_path2=r"D:\temp\pic2.jpg"
carry_img=plt.imread(img_path1)
info_img=plt.imread(img_path2)
hidden_img=InfoHidden(carry_img,info_img,1)
plt.imshow(hidden_img)
plt.show(block=True)
recovered_img=InfoExtrac(hidden_img,1)
plt.axis('off')
plt.title('recovered image')
plt.imshow(recovered_img)
plt.show(block=True)

结果展示

待隐藏图片:

载体图片:

隐藏后图片:

复原图片:

可以看到隐藏效果还是很不错的,只是因为用的图都是彩色图样,所以存在着差异,如果是灰度图,恢复效果会十分优秀。

相关推荐
Adolf_19933 分钟前
Flask-JWT-Extended登录验证, 不用自定义
后端·python·flask
冯宝宝^3 分钟前
基于mongodb+flask(Python)+vue的实验室器材管理系统
vue.js·python·flask
qq_153214526414 分钟前
【2023工业异常检测文献】SimpleNet
图像处理·人工智能·深度学习·神经网络·机器学习·计算机视觉·视觉检测
叫我:松哥15 分钟前
基于Python flask的医院管理学院,医生能够增加/删除/修改/删除病人的数据信息,有可视化分析
javascript·后端·python·mysql·信息可视化·flask·bootstrap
Eiceblue1 小时前
Python 复制Excel 中的行、列、单元格
开发语言·python·excel
NLP工程化1 小时前
对 Python 中 GIL 的理解
python·gil
极客代码1 小时前
OpenCV Python 深度指南
开发语言·人工智能·python·opencv·计算机视觉
liO_Oil1 小时前
(2024.9.19)在Python的虚拟环境中安装GDAL
开发语言·python·gdal安装
simplesin1 小时前
OpenCV 1
人工智能·opencv·计算机视觉
奈斯。zs2 小时前
yjs08——矩阵、数组的运算
人工智能·python·线性代数·矩阵·numpy