数字水印_最低有效位算法
原文链接:https://blog.csdn.net/chengfenglee/article/details/123771536
最低有效位( Least Significant Bit.,LSB)指的是一个二进制数中的第0位(即最低位)
最低有效位信息隐藏指的是,将一个需要隐藏的二值图像信息嵌入载体图像的最低有效位,即将载体图像的最低有效位层替换为当前需要隐的二值图像,从而实现将二值图像隐藏的目的由于二值图像处于载体图像的最低有效位上,所以对于载体图像的影响非常不明显,其具有较高的隐酸性
在必要时直接将载体图像的最低有效位层提取出来,即可得到嵌入在该位上的二值图像,达到提取秘密信息的目的
这种信息隐藏也被称为数字水印,递过该方式可以实现信息隐藏、版权认证、身份认证功能,例如,如果嵌入载体图像内的信息是秘密信息,就实现了信息隐藏:如果嵌入载体图像值内的信息是版权信息,就能够实现版权认证:如果嵌入载体图像内的信息是身份信息,就可以实现数字签名,等等。所以,被嵌入载体图像内的信息也被称为数字水印信息。
数字水印信息可以是文本、视频、音频等多种形式,这里我们仅讨论数字水印信息是二值
图像的情况。
3.8.1 原理
从位平面的角度考虑,数字水印的处理过程分为下面两步
1.嵌入过程:将载体图像的第0 个位平面替换为数字水印信息(一幅二值图像)。
2.提取过程:将载体图像的最低有效位所构成的第0 个位平面提取出来,得到数字水印信息
1.嵌入过程
嵌入过程是将数字水印嵌入载体图像的过程。该过程实现的是,将载体图像的最低有效位
数字水印信息替换,得到包含水印信息的载体图像
为了处理和说明起来方便,这里以原始图像为灰度图像、水印图像为二值图像为例。在实
际处理中,原始图像、水印图像均可以为彩色图像,这时需要先对它们进行通道分解、图层分解,后续的处理方法与在灰度图像内嵌入二值水印图像的处理方法相同
(1)原始载体图像预处理
为了便于理解,我们将载体图像处理为二进制形式,并标记出最低有效位
例如,有灰度图像O作为载体图像,图像O 中各个像素点的像素值为:
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 209 | 197 | 163 | 193 |
2 | 125 | 247 | 160 | 112 |
3 | 161 | 137 | 243 | 203 |
4 | 39 | 82 | 154 | 127 |
其对应的二进制表示OB为:
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 1101 000[1] | 1100 010[1] | 1010 001[1] | 1100 000[1] |
2 | 0111 110[1] | 1111 011[1] | 1010 000[0] | 0111 000[0] |
3 | 1010 000[1] | 1000 100[1] | 1111 001[1] | 1100 101[1] |
4 | 0010 011[1] | 0101 001[0] | 1001 101[0] | 0111 111[1] |
为了更直观,我们用下划线将图像额二进制表示为OB的最低有效位标记出来了,被标记的值构成了载体图像O的第0个位平面,即"最低有效位"位平面OBLSB 其具体值为:
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 1 | 1 | 1 | 1 |
2 | 1 | 1 | 0 | 0 |
3 | 1 | 1 | 1 | 1 |
4 | 1 | 0 | 0 | 1 |
2)水印图像处理
为了方便处理,在嵌入水印前,需要将水印信息处理为二值图像,比较典型的情况是将灰度二值水印信息进行阀值处理,将其处理为二进制二值水印信息
在灰度二值图像中,像素值只有0和 255 两种类型值,分别用来表示黑色和白色,可以将其中的 255 转换为 1,这样就得到了一幅二进制二值图像,在二进制二值图像中,仅仅用一个比特位表示一个像素值,像素值只有0和1 两种可能值,经过上述处理,能够更方便地实现水印嵌入
例如,有灰度二值水印图像W,其像素值为
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 255 | 0 | 255 | 0 |
2 | 255 | 255 | 0 | 255 |
3 | 0 | 0 | 0 | 0 |
4 | 255 | 255 | 0 | 255 |
不能直接将上述水印图像嵌入载体图像内,需要将其转换为二进制二值水印图像,以方便嵌入,通过阀值处理,得到二进制二值水印图像 WB,其具体值为:
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 1 | 0 | 1 | 0 |
2 | 1 | 1 | 0 | 1 |
3 | 0 | 0 | 0 | 0 |
4 | 1 | 1 | 0 | 1 |
经过处理后,二进制二值水印信息正好可以嵌入载体图像的最低有效位上
(3)嵌入水印
将载体图像的最低有效位替换为二进制水印图像,完成水印的嵌入
例如,将载体图像OB 的最低有效位用水印信息 WB 替换,得到含水印载体图像的二进制形式 WOB,其具体值为
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 1101 000[1] | 1100 010[0] | 1010 001[1] | 1100 000[0] |
2 | 0111 110[1] | 1111 011[1] | 1010 000[0] | 0111 000[1] |
3 | 1010 000[0] | 1000 100[0] | 1111 001[0] | 1100 101[0] |
4 | 0010 011[1] | 0101 001[1] | 1001 101[0] | 0111 111[1] |
将 WOB 转为十进制形式,即得到含水印载体图像的十进制值形式 WO,其值为:
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 209 | 196 | 163 | 192 |
2 | 125 | 247 | 160 | 113 |
3 | 160 | 136 | 242 | 202 |
4 | 39 | 83 | 154 | 127 |
由于信息的最低有效位对值的大小影响有限,因此,将载体图像最低有效位的值用水印信息替换后,载体图像作素的值并没有发生太大变化,人眼不足以看出区别,水印具有较高的隐藏性
(2) 提取过程
提取过程是指将水印信息从包含水印信息的载体图像内提取出来的过程。提取水印时,先将含水印载体图像的像素值转换为二进制形式,然后从其最低有效位提取出水印信息即可,因此,可以通过提取含水印载体图像的“最低有效位”位平面的方式来得到水印信息
例如,有包含水印信息的载体图像 WOE,其具体值为
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 209 | 196 | 163 | 192 |
2 | 125 | 247 | 160 | 113 |
3 | 160 | 136 | 242 | 202 |
4 | 39 | 83 | 154 | 127 |
将含水印信息的载体图像 WOE 转换为二进制形式 WOE,得到
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 1101 000[1] | 1100 010[0] | 1010 001[1] | 1100 000[0] |
2 | 0111 110[1] | 1111 011[1] | 1010 000[0] | 0111 000[1] |
3 | 1010 000[0] | 1000 100[0] | 1111 001[0] | 1100 101[0] |
4 | 0010 011[1] | 0101 001[1] | 1001 101[0] | 0111 111[1] |
提取 WOEB 的最低有效位信息(“最低有效位”位平面,即第0 个位平面),即可得到水印信息WE,其值为:
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 1 | 0 | 1 | 0 |
2 | 1 | 1 | 0 | 1 |
3 | 0 | 0 | 0 | 0 |
4 | 1 | 1 | 0 | 1 |
根据需要,决定是否进行阈值处理,如有必要,则通过阈值处理将其中值为1 的像素点经换为 255, 得到含有0和 255 两个值的二值水印图像 WET,具体值为
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 255 | 0 | 255 | 0 |
2 | 255 | 255 | 0 | 255 |
3 | 0 | 0 | 0 | 0 |
4 | 255 | 255 | 0 | 255 |
通过上述例题可以发现,经过上述处理后,得到的水印图像 WET 与嵌入的水印图像W是一致的
为了便于理解,这里仅介绍了原始载体图像为灰度图像的情况,在实际中可以很据需多个通道内嵌入相同的水印(提高鲁棒性,即使部分水印丢失,也能提取出完整水印信息或在各个不同的通道内嵌入不同的水印(提高嵌入容量)。在彩色图像的多个通道内的方法,与在灰度图像内嵌入水印的方法相同。
3.82 实现方法
最低有效位水印的实现包含嵌入过程和提取过程。下面对具体的实现方法进行简单介绍
1.嵌入过程
嵌入过程完成的操作是,将数字水印信息嵌入载体图像内,主要步骤为
1)载体图像预处理
读取原始载体图像,并获取载体图像的行数M 和列数N
例如,有原始载体图像O,其像素值为
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 179 | 177 | 136 | 83 |
2 | 207 | 87 | 226 | 227 |
3 | 222 | 117 | 11 | 84 |
4 | 85 | 231 | 52 | 189 |
将其对应的二进制形式记为 OB,其具体值为:
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 1011 001[1] | 1011 000[1] | 1000 100[0] | 0101 001[1 |
2 | 1100 111[1] | 0101 011[1] | 1110 001[0] | 1110 001[1] |
3 | 1101 111[0] | 0111 010[1] | 0000 101[1] | 0101 010[0] |
4 | 0101 010[1] | 1110 011[1] | 0011 010[0] | 1011 110[1] |
(2)建立提取矩阵
建立一个 MxN 大小、元素值均为 254 的提取矩阵(数组),用来提取载体图像的高七位
例如,按照原始图像O 的大小建立一个 4×4 大小、元素值均为 254 的数组T,其具体为
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 254 | 254 | 254 | 254 |
2 | 254 | 254 | 254 | 254 |
3 | 254 | 254 | 254 | 254 |
4 | 254 | 254 | 254 | 254 |
T 所对应的二进制形式记为 TB,其具体值为:
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 1111 1110 | 1111 1110 | 1111 1110 | 1111 1110 |
2 | 1111 1110 | 1111 1110 | 1111 1110 | 1111 1110 |
3 | 1111 1110 | 1111 1110 | 1111 1110 | 1111 1110 |
4 | 1111 1110 | 1111 1110 | 1111 1110 | 1111 1110 |
(3)保留载体图像的高七位,将最低位置零
为了实现该操作,需要将载体图像与元素值均为 254 的提取矩阵进行按位与运算.
将一个值在 [0,255]之间的像素值P 与数值 254 进行按位与运算,则会将像素值P 的最低有位置零,只保留其高七位。
例如
1.某个像素 Pa 的像素值为 217,将像素 Pa与 254 进行按位与运算,则像素 Pa的二进制像素值高七位保持不变,最低有效位被清零,像素 Pa 的最低有效位上原来的值是1因此,经过运算后像素P 的像素值 217 减少 1,变为 216.
2.某个像素 Pb 的像素值为 216,将像素P与 254 进行按位与运算,则像素P 的二进制像素值高七位保持不变,最低有效位被清零,像素 Pb 的最低有效位上原来的值就是0 因此在运算后像素 Pb 的像素值仍然是 216.
该运算示例具体如表 3-17 所示
| 运算 |运算值 |像素P的LSB为1 | 像素P的LSB为0 |
| --- | --- | --- | --- | --- |--- |
运算 | 运算值 | 二进制 | 十进制 | 二进制 | 十进制 |
---|---|---|---|---|---|
1 | bit_and | 像素P的值 | 1101 1001 | 217 | 1101 1000 |
2 | bit_and | 数值254 | 1111 1110 | 254 | 1111 1110 |
3 | 运算结果 | 运算结果 | 1101 1000 | 216 | 1101 1000 |
表中的 LSB 表示 Least Signiflcant H,即最低有效位
根据以上分析,将载体图像与元素值均为 254 的提取矩阵进行按位与运算,相当于将载体图像内的每个像素值均与值 254 进行按位与运算。这样就实现了将整个图像内所有像素二进制 值的高七位保留、最低位置零
例如,将原始较体图像OB 与元素值均为 254 的提取矩阵TB 进行按位与运算,则OB的高七位保持不变,而最低有效位被置零。即实现了只保留OB 的高七位,得到 OBH,其具体为:
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 1011 001[0] | 1011 000[0] | 1000 100[0] | 0101 001[0 |
2 | 1100 111[0] | 0101 011[0] | 1110 001[0] | 1110 001[0] |
3 | 1101 111[0] | 0111 010[0] | 0000 101[0] | 0101 010[0] |
4 | 0101 010[0] | 1110 011[0] | 0011 010[0] | 1011 110[0] |
【提示】要保留图像的高七位,还有一种实现方法,即先对像素进行右移一位的位操作 选行左移一位的位操作
(4)水印图像处理
有应情况下票对水印进行简单处理。例如,当水印图像为8 位灰度图的二值图像时,需要将其转换为一进制二值图像,以方便将其嵌入较体图像的最低位。
例如,有一幅灰度二值水印图像W,具体值为
- 1
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 255 | 255 | 255 | 255 |
2 | 255 | 255 | 255 | 255 |
3 | 255 | 0 | 255 | 0 |
4 | 0 | 0 | 255 | 255 |
我们将其中的像素值 255 转换为像素值 1.以方便联入载体图像。该灰度二值图像对应的二进制图像为 WT,其值具体为:
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 1 | 1 | 1 | 1 |
2 | 1 | 1 | 1 | 1 |
3 | 1 | 0 | 1 | 0 |
4 | 0 | 0 | 1 | 1 |
其对应的8 位二进制形式 WTB为:
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 0000 000[1] | 0000 000[1] | 0000 000[1] | 0000 000[1] |
2 | 0000 000[1] | 0000 000[1] | 0000 000[1] | 0000 000[1] |
3 | 0000 000[1] | 0000 000[0] | 0000 000[1] | 0000 000[0] |
4 | 0000 000[0] | 0000 000[0] | 0000 000[1] | 0000 000[1] |
(5)嵌入水印
将原始载体图像进行“保留高七位、最低位置零”的操作后,我们得到一幅新的图像,将新图像与水印图像进行按位成运算,就能实现将水印信息嵌入原始载体图像内的效果
将一个最低有效位(LSB)为0 的数值A 与一个只有一位的二进制值B(单位二进制值)进行按位或运算时:
1.当该二进制值B为0时,按位或运算的结果是 0.数值A 的值保持不变,由于B的值为 0.因此,如果从最低有效位的角度理解,可以理解为数值A 的最低有效位被替换为单位二进制值B 的值,也可以理解为将单位二进制值B 嵌入数值A内(的最低有效位上)
2.当该二进制值B为1时,按位或运算的结果是 1,数值A 的高七位保持不变,而最低有效位变为 1.因此,如果从最低有效位的角度理解,可以理解为数值A 的最低有效位被换为单位二进制值B 的值,也可以理解为将单位二进制值B 嵌入数值A内(的最低有效位上)
总结来看,将一个最低有效位(LSB)为0 的数值A 与一个单位二进制值B 进行按位或运算,相当于用该单位二进制值B 替换原始数值A 的最低有效位,即可以实现将单位二进制值B入数值A 的最低有效位上
例如,将最低有效位是0 的数字 216 分别与单位二进制值0 和单位二进制值1 进行按位或运算,如表 3-18 所示
| 运算值 |二进制值B 为1 即数值A与数值1进行按位或运算 | 二进制值B 为0 即数值A与数值0 进行按位或运算 |
| 运算值 | 二进制 | 十进制 | 二进制 | 十进制 |
| --- | --- | --- | --- | --- |--- |
| 1 | 数值A | 1101 1000 | 216 | 1101 1000 | 217 |
| 2 | 单位二进制数值B | 0000 0001 |1 |0000 0000 | 0 |
| 3 | 运算结果 | 运算结果 | 1101 1001 | 217 |1101 1000 | 216 |
可以推断,如果将二进制二值水印图像(单位二进制值的水印图像)与最低有效位被置零得到的原始载体图像进行按位或运算,就可以实现将水印信息嵌入原始载体图像内
因此,将水印图像WB 与原始载体图像O 高七位图像 OBH 进行按位或运算,即完成将水印信息嵌入原始载体图像O的OBH内
就可以得到含水印载体图像WO,WO的具体指为:
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 1011 001[1] | 1011 000[1] | 1000 100[1] | 0101 001[1] |
2 | 1100 111[1] | 0101 011[1] | 1110 001[1] | 1110 001[1] |
3 | 1101 111[1] | 0111 010[0] | 0000 101[1] | 0101 010[0] |
4 | 0101 010[0] | 1110 011[0] | 0011 010[1] | 1011 110[1] |
(6)显示图像
完成上述处理后,分别显示原始载体图像、水印图像,含水印图像
2.提取过程
提取过程将完成数字水印的提取,具体步骤如下
(1)含水印载体图像处理
读取包含水印的载体图像,获取含水印载体图像的大小 MXN
例如,读取含水印载体图像 WO,获取其大小为 4×4.WO 的具体值为
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 1011 001[1] | 1011 000[1] | 1000 100[1] | 0101 001[1] |
2 | 1100 111[1] | 0101 011[1] | 1110 001[1] | 1110 001[1] |
3 | 1101 111[1] | 0111 010[0] | 0000 101[1] | 0101 010[0] |
4 | 0101 010[0] | 1110 011[0] | 0011 010[1] | 1011 110[1] |
(2)建立提取矩阵
定义一个与含水印载体图像等大小的值为1 的矩阵(数组)作为提取矩阵。
例如,定义一个大小为 4×4 的矩阵作为提取矩阵,使其中的值均为 1,将该矩阵标记为T1:
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 1 | 1 | 1 | 1 |
2 | 1 | 1 | 1 | 1 |
3 | 1 | 1 | 1 | 1 |
4 | 1 | 1 | 1 | 1 |
其对应的8 位二进制形式 Te为:
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 0000 000[1] | 0000 000[1] | 0000 000[1] | 0000 000[1] |
2 | 0000 000[1] | 0000 000[1] | 0000 000[1] | 0000 000[1] |
3 | 0000 000[1] | 0000 000[1] | 0000 000[1] | 0000 000[1] |
4 | 0000 000[1] | 0000 000[1] | 0000 000[1] | 0000 000[1] |
(3)提取水印信息
将含水印载体图像与提取矩阵进行按位与运算,提取水印信息
将一个值在 [0.255] 之间的像素P 与数值1 进行按位与运算,则会将像素P 的像素值的高七位置零,只保留像素P 的最低有效位(LSB)。
下面分别以像素P 的最低有效位为0和1 为例进行说明。
如果像素P 的最低有效位为 1,则会得到值1
例如,某像素 Pa 的值为 217,将其与数值1 进行按位与运算,则 Pa 的高七位被置零,只有其最低有效位被保留,得到值1.
如果像素P 的最低有效位为 0,则会得到值0
例如,某像素 Pb 的值为 216,将其与数值1 进行按位与运算,则 Pb 的高七位被置零,只有其最低有效位被保留,得到值0
该实例的具体计算如表 319 所示
| 运算 |运算值 |像素P的LSB为1 | 像素P的LSB为0 |
| --- | --- | --- | --- | --- |--- |
运算 | 运算值 | 二进制 | 十进制 | 二进制 | 十进制 |
---|---|---|---|---|---|
1 | bit_and | 像素P的值 | 1101 1001 | 217 | 1101 1000 |
2 | bit_and | 数值1 | 0000 0001 | 1 | 0000 0001 |
3 | 运算结果 | 运算结果 | 0000 0001 | 1 | 0000 0000 |
基于上述规则,针对图像内的每个像素,将其与数值1 进行按位与操作,即可将图像的最低有效位提取出来
因此,可以将含水印载体图像与元素值均为1 的提取矩阵进行按位与运算,以实现提取水印信息
例如,含水印载体图像WO为:
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 1011 001[1] | 1011 000[1] | 1000 100[1] | 0101 001[1] |
2 | 1100 111[1] | 0101 011[1] | 1110 001[1] | 1110 001[1] |
3 | 1101 111[1] | 0111 010[0] | 0000 101[1] | 0101 010[0] |
4 | 0101 010[0] | 1110 011[0] | 0011 010[1] | 1011 110[1] |
将含水印图像 WO 与提取矩阵 Te 进行按位与运算,即可得到二进制值水印信息 we,其值为
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 1 | 1 | 1 | 1 |
2 | 1 | 1 | 1 | 1 |
3 | 1 | 0 | 1 | 0 |
4 | 0 | 0 | 1 | 1 |
将提取出来的二进制水印信息We 进行阀值处理,将其中值为1 的像素值调整为255,以便显示,阀值处理后,得到二值水印图像 WG,具体值为
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 255 | 255 | 255 | 255 |
2 | 255 | 255 | 255 | 255 |
3 | 255 | 0 | 255 | 0 |
4 | 0 | 0 | 255 | 255 |
(4)计算去除水印后的载体图像
有时需要删除包含在水印载体图像内的水印信息,通过将含水印载体图像的最低有效位置,即可实现删除水印信息
建立一个大小为 4x4、元素值均为 254 的矩阵,将该矩阵标记为 T2,其具体为:
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 254 | 254 | 254 | 254 |
2 | 254 | 254 | 254 | 254 |
3 | 254 | 254 | 254 | 254 |
4 | 254 | 254 | 254 | 254 |
将上述 T2 所对应的二进制形式记为 TB,其具体值为
序号 | 值1 | 值2 | 值3 | 值4 |
---|---|---|---|---|
1 | 1111 1110 | 1111 1110 | 1111 1110 | 1111 1110 |
2 | 1111 1110 | 1111 1110 | 1111 1110 | 1111 1110 |
3 | 1111 1110 | 1111 1110 | 1111 1110 | 1111 1110 |
4 | 1111 1110 | 1111 1110 | 1111 1110 | 1111 1110 |
通过将含水印载体图像WO与TB 进行按位与运算,即可将载体图像 WO 的最低有效位置零,得到删除水印信息的载体图像 ODW,该操作的具体实现原理及过程,与水印嵌入时对原始图像的的最有效位置操作是类似的
(5)显示图像
根据需要,分别显示提取出来的水印图像WG、删除水印信息的载体图像 ODW
【提示】将像素值对2 取模,可以获取像素值的最低有效位。因此,可以通过让含水印载体困像对2 取模的方式,获取图像的“最低有效位”位平面,提取到的位平面即为水印信息
就是说 也可以通过让含水印载体图像像素值对2取模的方式,来获取最低有效位水印
3.8.3 例题
【例 3.15】编写程序,模拟数字水印的嵌入和提取过程
根据题目要求,编写代码如下
import cv2
import numpy as np
#读取原始载体图像
lena=cv2.imread("lena.bmp",0)
#读取水印图像
watermark=cv2.imread("watermark.bmp",0)
#将水印内的255处理为1,以方便嵌入
#后续章节会介绍使用threshold处理。
w=watermark[:,:]>0
watermark[w]=1
#读取原始载体图像的shape值
r,c=lena.shape
#============嵌入过程============
#生成内部值都是254的数组
t254=np.ones((r,c),dtype=np.uint8)*254
#获取lena图像的高7位
lenaH7=cv2.bitwise_and(lena,t254)
#将watermark嵌入到lenaH7内
e=cv2.bitwise_or(lenaH7,watermark)
#============提取过程============
#生成内部值都是1的数组
t1=np.ones((r,c),dtype=np.uint8)
#从载体图像内,提取水印图像
wm=cv2.bitwise_and(e,t1)
print(wm)
#将水印内的1处理为255以方便显示
#后续章节会介绍threshold实现。
w=wm[:,:]>0
wm[w]=255
#============显示============
cv2.imshow("lena",lena)
cv2.imshow("watermark",watermark*255) #当前watermark内最大值为1
cv2.imshow("e",e)
cv2.imshow("wm",wm)
cv2.waitKey()
cv2.destroyAllWindows()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
1561995679(1).png
1.图(a) 是原始图像lena
2.图(b)是水印图像 watermark。在程序中,该图像首先会被处理为二值图像,在显示时将其元素值乘以 255,以方使显示。
- 图©是在图像 lema 内嵌入水印图像 watermark 后得到的含水印线体图像e
4.图(d)是从含水印线体图像e 内提取到的水印图像 wm
从图 3-14 可以发现,通过肉眼无法观察出含水印载体图像和原始图像的不同,水印的隐蔽性较高。但是,由于该方法过于简单,其安全性并不高,在实际处理中会通过更复杂的方式实现水即的嵌入。
标签:载体,二进制,数字水印,最低,水印,像素,算法,000,图像 From: https://www.cnblogs.com/sunny3158/p/17307303.html