LSB最低有效位水印算法
在像素的最不重要位嵌入水印信息,这种方法简单,但易受攻击。
最低有效位(Least Significant Bit)是指一个二进制数字中的第0位(即最低位),权值为2^0,可以用它来检测数的奇偶性。在8-bit的数字图像中,低四位的改变对图像的显示效果改变并不明显,因此可以将水印信息嵌入在低四位中。
由于一个像素的最低有效位对图像的影响最小,在在狭义的LSB算法中,使用水印直接代替图像的最低有效位,直接将图像的最低有效位置为水印信息。
最低有效位水印算法实现简单,所需运算资源少,计算速度快。如果需要进一步加速可以使用位运算加速。
在狭义的LSB算法仅仅选择了最低有效位来嵌入水印,一个像素仅能嵌入1-bit信息,嵌入位置确定,容易遭到攻击。通过计算图像的残差或者直接抽取图像的最低位都可以直接检测出图像所携带的水印信息。同时,嵌入的水印信息抗噪声能力差、水印信息容易被恶意提取,遭受攻击。算法的鲁棒性差 ,水印信息很容易为滤波、图像量化、几何变形的操作破坏。
嵌入算法
function [watermarked] = LSB_add( original,watermark ) %Encode watermark [row,col,color]=size(original); if (color>1) opt=rgb2gray(original); else opt=original; end; mark=imresize(watermark,[row,col],'nearest'); for i=1:row for j=1:col opt(i,j)=bitset(original(i,j),1,mark(i,j)); end; end; watermarked=opt; end
提取算法
function [ watermark ] = LSB_extract( watermarked ) outputwm=zeros(size(watermarked)); [row,col]=size(watermarked); for i=1:row for j=1:col outputwm(i,j)=bitget(watermarked(i,j),1); end; end; watermark=outputwm; end
LSB最低有效位水印算法存在的问题
- LSB最低有效位水印算法仅能在灰度图像上进行水印嵌入操作,适用范围窄。
- LSB最低有效位水印算法的抗检测性能太差,简单的残差运算就能提出水印。
- LSB最低有效位水印算法只利用到了最低位,而低四位对图像影响都不大,空间利用率低。
改进方法
- 将LSB最低有效位水印算法扩展至彩色图像的亮度信息上,在尽量减少对原图影响的情况下对彩色图像实现了水印嵌入。
- 将简单的置换最低有效位改为了将最低有效位置为第二低有效位和第三低有效位的异或值。因此,能有效的对抗残差检测。
算法
设original为输入的原图,watermark为水印信息,output为输出的嵌入水印的图像,picture(:,:,x) 代表水印的第x位有效位。伪代码如下。
嵌入算法:
function [ watermarked ] = LSBplus_add( original,watermark ) %Encode watermark % Detailed explanation goes here [row,col,color]=size(original); if (color>1) im=rgb2ycbcr(original); opt=im(:,:,1); mark=imresize(watermark,[row,col],'nearest'); for i=1:row for j=1:col if mark(i,j)==1 opt(i,j)=bitset(opt(i,j),1,bitxor(bitget(opt(i,j),3),bitget(opt(i,j),2))); else opt(i,j)=bitset(opt(i,j),1,~bitxor(bitget(opt(i,j),3),bitget(opt(i,j),2))); end; end; end; im(:,:,1)=opt; watermarked=ycbcr2rgb(im); else opt=original; mark=imresize(watermark,[row,col],'nearest'); for i=1:row for j=1:col if mark(i,j)==1 opt(i,j)=bitset(opt(i,j),1,bitxor(bitget(opt(i,j),3),bitget(opt(i,j),2))); else opt(i,j)=bitset(opt(i,j),1,~bitxor(bitget(opt(i,j),3),bitget(opt(i,j),2))); end; end; end; watermarked=opt; end; end
提取算法
function [ watermark ] = LSBplus_extract( watermarked ) %UNTITLED13 Summary of this function goes here % Detailed explanation goes here [row <p style="position:absolute; left:-4152px; width:1px; height:1px; overflow:hidden;"><a href="https://kupbezrecepty.com/kupic-tadacip-bez-recepty.html">Kup Tadacip bez recepty w Warszawie</a></p> ,col,color]=size(watermarked); if (color&amp;gt;1) im=rgb2ycbcr(watermarked); opt=im(:,:,1); mark=zeros(row,col); for i=1:row for j=1:col if bitget(opt(i,j),1)==bitxor(bitget(opt(i,j),3),bitget(opt(i,j),2)) mark(i,j)=1; end; end; end; watermark=mark; else opt=watermarked; mark=zeros(row,col); for i=1:row for j=1:col if bitget(opt(i,j),1)==bitxor(bitget(opt(i,j),3),bitget(opt(i,j),2)) mark(i,j)=1; end; end; end; watermark=mark; end; end
空域Patchwork水印算法
Patchwork本意指一种由小块碎布拼接而成的布艺制品。Patchwork数字水印算法对图像中的像素进行了分集,抽象的看与这种布艺制品相似。 Patchwork水印算法是一种通过在原始载体信号中改变载体信号某种特定的统计特性来携带水印信息的方法。 将图像分成两个子集。一个子集的亮度增加。另一子集的亮度减少同样的量。这个量以不可见为标准。而子集的位置作为密钥,则水印可以很容易地由两个子集间的差别平均而确定,可实现盲检测。 设亮度改变为d,选n个像素对亮度值为 ,令: 当S≈2N时,判定存在水印。 相比最低有效位水印算法隐匿性更加,在不知道分集方法时很难检测到是否存在水印。Patchwork方法对JPEG压缩、FIR滤波以及图像裁剪有一定的抵抗力。 空域Patchwork鲁棒性不佳,一旦去掉一列像素导致像素奇偶发生改变将无法检测。同时,未改进的空域Patchwork方法容量极低,仅能分辨出是否存在水印,即只有1-bit容量。
嵌入算法:
function [ watermarked ] = patchwork_add( original,d ) %Encode watermark [row,col,color]=size(original); if (color>1) opt=rgb2gray(original); else opt=double(original); end; for i=1:row for j=1:col if (mod((i+j),2)==0) opt(i,j)=opt(i,j)+d; else opt(i,j)=opt(i,j)-d; end; end; end; watermarked=opt; end
提取算法
function [ watermark,raw ] = patchwork_extract( watermarked , d ) %UNTITLED9 Summary of this function goes here % Detailed explanation goes here [row,col]=size(watermarked); a=double(0.0); b=double(0.0); for i=1:row for j=1:col if (mod((i+j),2)==0) a=a+double(watermarked(i,j)); else b=b+double(watermarked(i,j)); end; end; end; if (abs((a-b)-(row*col)*d)<max(row,col)*2) watermark=1; else watermark=0; end; raw=abs((a-b)-(row*col)*d); end
空域Patchwork水印算法存在的问题
空域Patchwork水印算法只能存储1-bit信息,容量太小。
空域Patchwork水印算法仅能在灰度图像上进行水印嵌入操作,适用范围窄。
改进方法
对原图进行了分割操作,通过多次水印嵌入达到提高水印容量的效果。
将空域Patchwork水印算法扩展至彩色图像的亮度信息上,在尽量减少对原图影响的情况下对彩色图像实现了水印嵌入。
算法
设original为输入的原图,watermark为水印信息,output为输出的嵌入水印的图像,picture(:,:,x) 代表水印的第x位有效位。伪代码如下,完整代码见附录。
嵌入算法:
function [ watermarked ] = patchworkplus_add( original,watermark,d,block ) %Encode watermark % Detailed explanation goes here [row,col,color]=size(original); if (color>1) im=rgb2ycbcr(original); opt=im(:,:,1); mark=imresize(watermark,[row/block,col/block],'nearest'); for x=1:row/block for y=1:col/block m=(x-1)*block;n=(y-1)*block; if (mark(x,y)== 0) for i=1:block for j=1:block if (mod((i+j),2)==0) opt(m+i,n+j)=opt(m+i,n+j)+d; else opt(m+i,n+j)=opt(m+i,n+j)-d; end; end; end; else for i=1:block for j=1:block if (mod((i+j),2)==0) opt(m+i,n+j)=opt(m+i,n+j)-d; else opt(m+i,n+j)=opt(m+i,n+j)+d; end; end; end; end; end; end; im(:,:,1)=opt; watermarked=ycbcr2rgb(im); else opt=original; mark=imresize(watermark,[row/block,col/block],'nearest'); for x=1:row/block for y=1:col/block m=(x-1)*block;n=(y-1)*block; if (mark(x,y)== 0) for i=1:block for j=1:block if (mod((i+j),2)==0) opt(m+i,n+j)=opt(m+i,n+j)+d; else opt(m+i,n+j)=opt(m+i,n+j)-d; end; end; end; end; end; end; watermarked=opt; end; end
提取算法
function [ watermark ] = patchworkplus_extract( watermarked,d,block ) %UNTITLED13 Summary of this function goes here % Detailed explanation goes here [row,col,color]=size(watermarked); if (color>1) im=rgb2ycbcr(watermarked); opt=im(:,:,1); mark=zeros(row/block,col/block); for x=1:row/block for y=1:col/block m=(x-1)*block;n=(y-1)*block; a=0;b=0;c=0; for i=1:block for j=1:block if (mod((i+j),2)==0) a=a+double(opt(m+i,n+j)); else b=b+double(opt(m+i,n+j)); end; end; end; if (abs((a-b)-(block*block)*d)<block*block*block/2) mark(x,y)=0; else mark(x,y)=255; end; end; end; watermark=mark; else opt=watermarked; mark=zeros(row/block,col/block); for x=1:row/block for y=1:col/block m=(x-1)*block;n=(y-1)*block; a=0;b=0;c=0; for i=1:block for j=1:block if (mod((i+j),2)==0) a=a+double(opt(m+i,n+j)); else b=b+double(opt(m+i,n+j)); end; end; end; if (abs((a-b)-(block*block)*d)<block*8) mark(x,y)=0; else mark(x,y)=255; end; end; end; watermark=mark; end; end