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)

结果展示

待隐藏图片:

载体图片:

隐藏后图片:

复原图片:

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

相关推荐
云空8 分钟前
《Python 与 SQLite:强大的数据库组合》
数据库·python·sqlite
凤枭香1 小时前
Python OpenCV 傅里叶变换
开发语言·图像处理·python·opencv
测试杂货铺1 小时前
外包干了2年,快要废了。。
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展
艾派森1 小时前
大数据分析案例-基于随机森林算法的智能手机价格预测模型
人工智能·python·随机森林·机器学习·数据挖掘
小码的头发丝、1 小时前
Django中ListView 和 DetailView类的区别
数据库·python·django
ctrey_2 小时前
2024-11-4 学习人工智能的Day21 openCV(3)
人工智能·opencv·学习
Chef_Chen2 小时前
从0开始机器学习--Day17--神经网络反向传播作业
python·神经网络·机器学习
千澜空3 小时前
celery在django项目中实现并发任务和定时任务
python·django·celery·定时任务·异步任务
可均可可3 小时前
C++之OpenCV入门到提高004:Mat 对象的使用
c++·opencv·mat·imread·imwrite
斯凯利.瑞恩3 小时前
Python决策树、随机森林、朴素贝叶斯、KNN(K-最近邻居)分类分析银行拉新活动挖掘潜在贷款客户附数据代码
python·决策树·随机森林