数字水印实验4 基于BTC的信息隐藏实验

【实验名称】基于BTC的信息隐藏实验       

 

【实验目的】

1、加深对图像信息隐藏基本原理和方法的掌握

2、学习并实现基于BTC的信息隐藏和提取算法

 

【实验原理】

1、将图像分成n×n数字水印实验4 基于BTC的信息隐藏实验大小的子块

2、计算子块的像素均值、高均值H和低均值I。根据均值进一步将原图像修改为二进制位图B。

3、在绝对矩阵块截断编码(AMBTC)生成的高低平均值序列上隐藏秘密信息。

 

【实验内容】

代码:

function BTC()
clc;clear;close all;
I=imread('coverlena.bmp');
figure;subplot(1,2,1);imshow(I);
title('原图');
Secret=10;                           %待隐藏数据的大小
block=4;                             %子块大小
data=round(rand(1,Secret));          %随机生成大小为Secret的待隐藏的2进制数据
fprintf('隐藏数据:');disp(data);
[length,width]=size(I);
High=zeros(length/block,width/block);
Low=zeros(length/block,width/block);
for i=1:block:256
    for j=1:block:256
        all=sum(sum(I(i:i+block-1,j:j+block-1),1),2);
        average=all/(block^2);
        high=0;low=0;num1=0;num2=0;
        for q=i:i+block-1
            for p=j:j+block-1
                if I(q,p)>average
                    high=high+double(I(q,p));
                    num1=num1+1;
                else
                    low=low+double(I(q,p));
                    num2=num2+1;
                end
            end
        end
        High(((i-1)/block)+1,((j-1)/block)+1)=round(high/num1);
        Low(((i-1)/block)+1,((j-1)/block)+1)=round(low/num2);
        I(i:i+block-1,j:j+block-1)=I(i:i+block-1,j:j+block-1)>average;
    end
end

point=1;
for i=1:length/block
    if point>Secret
        break;
    end
    for j=i:width/block
        %将数据隐藏进High数组
        if point>Secret
            break;
        end
        if point==Secret-mod(Secret,3)+1      %剩余数据不足三位时单独处理
            High(i,j)=fix(double(High(i,j))/8);
            High(i,j)=High(i,j)*8;
            if mod(Secret,3)==1
                fprintf('待隐藏数据:%-3d  隐藏进High数组  隐藏前值为:%d',data(point),High(i,j));
                High(i,j)=High(i,j)+data(point)*4;
                point=point+1;
            end
            if mod(Secret,3)==2
                fprintf('待隐藏数据:%d%-2d  隐藏进High数组  隐藏前值为:%d',data(point),data(point+1),High(i,j));
                High(i,j)=High(i,j)+data(point)*4+data(point+1)*2;
                point=point+2;
            end
            fprintf('  隐藏后值为:%d\n',High(i,j));
            break;
        end
        fprintf('待隐藏数据:%d%d%d  隐藏进High数组  隐藏前值为:%d',data(point),data(point+1),data(point+2),High(i,j));
        High(i,j)=fix(double(High(i,j))/8);   %后三位置0,放入待隐藏数据
        High(i,j)=High(i,j)*8;
        High(i,j)=High(i,j)+data(point)*4+data(point+1)*2+data(point+2);
        fprintf('  隐藏后值为:%d\n',High(i,j));
        point=point+3;
        
        %将数据隐藏进Low数组
        if point>Secret
            break;
        end
        if point==Secret-mod(Secret,3)+1      %剩余数据不足三位时单独处理
            Low(i,j)=fix(double(Low(i,j))/8);
            Low(i,j)=Low(i,j)*8;
            if mod(Secret,3)==1
                fprintf('待隐藏数据:%-3d  隐藏进Low 数组  隐藏前值为:%d',data(point),Low(i,j));
                Low(i,j)=Low(i,j)+data(point)*4;
                point=point+1;
            end
            if mod(Secret,3)==2
                fprintf('待隐藏数据:%d%-2d  隐藏进Low 数组  隐藏前值为:%d',data(point),data(point+1),Low(i,j));
                Low(i,j)=Low(i,j)+data(point)*4+data(point+1)*2;
                point=point+2;
            end
            fprintf('  隐藏后值为:%d\n',Low(i,j));
            break;
        end
        fprintf('待隐藏数据:%d%d%d  隐藏进Low 数组  隐藏前值为:%d',data(point),data(point+1),data(point+2),Low(i,j));
        Low(i,j)=fix(double(Low(i,j))/8);     %后三位置0,放入待隐藏数据
        Low(i,j)=Low(i,j)*8;
        Low(i,j)=Low(i,j)+data(point)*4+data(point+1)*2+data(point+2);
        fprintf('  隐藏后值为:%d\n',Low(i,j));
        point=point+3;
    end
end
fprintf('信息隐藏成功!\r\n');
fprintf('将压缩图像信息传送至接收方\r\n');
fprintf('恢复图像并显示\n');

%恢复图像
for i=1:block:length
    for j=1:block:width
        
        for q=i:i+block-1
            for p=j:j+block-1
                if I(q,p)==1
                    I(q,p)=High(((i-1)/block)+1,((j-1)/block)+1);
                else
                    I(q,p)=Low(((i-1)/block)+1,((j-1)/block)+1);
                end
            end
        end
        
    end
end
subplot(1,2,2);imshow(I);title('压缩图');

%隐藏信息读取
point=1;
for i=1:length/block
    if point>Secret
        break;
    end
    for j=i:width/block
        %High数组隐藏数据读取
        if point>Secret
            break;
        end
        if point==Secret-mod(Secret,3)+1      %之前做单独放入处理的隐藏点进行单独读取
            message=double(mod(High(i,j),8));
            message=floor(message/2);
            if mod(Secret,3)==1
                message=floor(message/2);
                Data(point)=mod(message,2);
                point=point+1;
            end
            if mod(Secret,3)==2
                Data(point+1)=mod(message,2);
                message=floor(message/2);
                Data(point)=mod(message,2);
                point=point+2;
            end
            break
        end
        message=double(mod(High(i,j),8));     %读取放置在后三位的隐藏数据
        Data(point+2)=mod(message,2);
        message=floor(message/2);
        Data(point+1)=mod(message,2);
        message=floor(message/2);
        Data(point)=mod(message,2);
        point=point+3;
        
        %Low数组隐藏数据读取
        if point>Secret
            break;
        end
        if point==Secret-mod(Secret,3)+1      %之前做单独放入处理的隐藏点进行单独读取
            message=double(mod(Low(i,j),8));
            message=floor(message/2);
            if mod(Secret,3)==1
                message=floor(message/2);
                Data(point)=mod(message,2);
                point=point+1;
            end
            if mod(Secret,3)==2
                Data(point+1)=mod(message,2);
                message=floor(message/2);
                Data(point)=mod(message,2);
                point=point+2;
            end
            break
        end
        message=double(mod(Low(i,j),8));      %读取放置在后三位的隐藏数据
        Data(point+2)=mod(message,2);
        message=floor(message/2);
        Data(point+1)=mod(message,2);
        message=floor(message/2);
        Data(point)=mod(message,2);
        point=point+3;
    end
end
fprintf('提取数据:');disp(Data);
end

实验结果:

数字水印实验4 基于BTC的信息隐藏实验

数字水印实验4 基于BTC的信息隐藏实验

实验结果分析:

由于图片经过压缩的缘故,可以看出压缩并隐藏了信息后恢复出来的图像有明显的失真。

仔细观察每一步隐藏信息的过程

1、待隐藏数据:110,隐藏进High数组,隐藏前值为:162

将162二进制的后三位抹除,得160,放入待隐藏数据110,得166

2、待隐藏数据:100,隐藏进Low 数组,隐藏前值为:158

将158二进制的后三位抹除,得152,放入待隐藏数据100,得156

3、待隐藏数据:110,隐藏进High数组,隐藏前值为:159

将159二进制的后三位抹除,得152,放入待隐藏数据110,得158

4、待隐藏数据:1  ,隐藏进Low 数组,隐藏前值为:152

将158二进制的后三位抹除,得152,放入待隐藏数据1(待隐藏数据位数不够则按二进制位从高位到地位隐藏,不够处补0)即放入100,得156

将手动推算结果和实验结果对比,可以看出实验正确。

 

【小结或讨论】

本次实验是第四次实验,实验主要内容是学习并实现基于BTC的信息隐藏和提取算法。

总体来说,基于BTC的信息隐藏实验难度和复杂度都比上一次的龟壳实验低。这个算法的信息隐藏过程使用的是上一次LSB实验的方法,所以对我们来说还是比较得心应手的。但是这个算法的亮点是BTC压缩算法的应用,这也是本实验与之前实验的最大不同之处。因为在当前实际的图片传输中,图片往往是进行压缩传送的。而如果基于我们之前学习的几个图片信息隐藏算法,在进行图片压缩后,图像中的隐藏信息全都会丢失。所以本次实验的基于BTC的信息隐藏算法,主要实现的是既对图片进行了压缩,又能将秘密信息隐藏进图片。

基于BTC的信息隐藏算法基本实现过程是:
1、将图像分成n×n数字水印实验4 基于BTC的信息隐藏实验(本实验中以4×4数字水印实验4 基于BTC的信息隐藏实验为例,修改代码第7行的block值即可)大小的子块。

2、计算子块的像素均值以及大于子块均值的所有像素点的高均值H和小于子块均值的所有像素点的低均值I。并将大于子块均值的所有像素点值置1,小于子块均值的所有像素点值置0。

3、在生成的高低平均值序列上使用LSB算法,隐藏秘密信息。

4、将压缩图像信息传送至接收方(这一步是对应实际中的模拟操作,并不是在代码中的真实实现)

5、恢复图像并显示(子块越大,图像失真越大)

6、提取隐藏数据

通过本次实验,我对压缩算法的原理有了一定的了解,并且对LSB信息隐藏算法进行了巩固。希望在后续实验中不断提高自己的能力。