基于DCT信息隐藏 数字水印 DCT matlab实现

1、DCT变化
在这里插入图片描述
2、DCT中频:
中频指DCT变化后从左上到右下的线经过点

3、代码实现

%------------------------------------------------------------------%
%     基于DCT变换的信息隐藏(数字水印)     %%                                                                %%                                                                %
%-----------------------------------------------------------=------%
clear ;
clc;

%-----------------------读入图像-------------------------------------%
markbefore=imread('lena.bmp');
markbefore=imresize(markbefore,[100,100],'nearest'); 
markbefore2=rgb2gray(markbefore);
mark=im2bw(markbefore2);    %使水印图像变为二值图
figure(1);      %打开窗口
subplot(2,3,1);    %该窗口内的图像可以有两行三列
imshow(mark),title('水印图像');   %显示水印图像
[rm,cm]=size(mark);   %计算水印图像的长宽
 
cover_image=imread('embedding_result.png');
cover_image=rgb2gray(cover_image);
subplot(2,3,2),imshow(cover_image,[]),title('载体图像'); %[]表示显示时灰度范围为image上的灰度最小值到最大值
 
before=blkproc(cover_image,[8 8],'dct2');   %将载体图像的灰度层分为8×8的小块,每一块内做二维DCT变换,结果记入矩阵before
 
I=mark;
alpha=5;     %尺度因子,控制水印添加的强度,决定了频域系数被修改的幅度

after=before;   %初始化载入水印的结果矩阵
for i=1:rm          %在中频段嵌入水印
    for j=1:cm
        x=(i-1)*8;
        y=(j-1)*8;
        if mark(i,j)==1
            k=1;
        else
            k=-1;
        end
        after(x+1,y+8)=before(x+1,y+8)*(1+alpha*k);
        after(x+2,y+7)=before(x+2,y+7)*(1+alpha*k);
        after(x+3,y+6)=before(x+3,y+6)*(1+alpha*k);
        after(x+4,y+5)=before(x+4,y+5)*(1+alpha*k);
        after(x+5,y+4)=before(x+5,y+4)*(1+alpha*k);
        after(x+6,y+3)=before(x+6,y+3)*(1+alpha*k);
        after(x+7,y+2)=before(x+7,y+2)*(1+alpha*k);
        after(x+8,y+1)=before(x+8,y+1)*(1+alpha*k);
    end
end
result=blkproc(after,[8, 8],'idct2');    %将经处理的图像分为8×8的小块,每一块内做二维DCT逆变换
result = uint8(result);
imwrite(result,'markresule.bmp','bmp');      %存储添加水印后的图像
subplot(2,3,3),imshow(result,[]),title('嵌入水印的图像');    %显示添加水印后的图像

%------------------------水印提取-----------------------------%
%
%src=imread('embedding_result.png');
%src=rgb2gray(src);
%srcs=blkproc(src,[8,8],'dct2');
srcs=before;
after_2=blkproc(result,[8,8],'dct2');   %此步开始提取水印,将灰度层分块进行DCT变换
p=zeros(1,8);        %初始化提取数值用的矩阵
mark_2 = zeros(rm,cm);
for i=1:rm
    for j=1:cm
        x=(i-1)*8;y=(j-1)*8;
        p(1)=(after_2(x+1,y+8)/srcs(x+1,y+8));         %将之前改变过数值的点的数值提取出来
        p(2)=(after_2(x+2,y+7)/srcs(x+2,y+7));
        p(3)=(after_2(x+3,y+6)/srcs(x+3,y+6));
        p(4)=(after_2(x+4,y+5)/srcs(x+4,y+5));
        p(5)=(after_2(x+5,y+4)/srcs(x+5,y+4));
        p(6)=(after_2(x+6,y+3)/srcs(x+6,y+3));
        p(7)=(after_2(x+7,y+2)/srcs(x+7,y+2));
        p(8)=(after_2(x+8,y+1)/srcs(x+8,y+1));
        f=((sum(p))/8-1)/alpha;
        if f>0  %corr2计算两个矩阵的相似度,越接近1相似度越大
            mark_2(i,j)=1;              %比较提取出来的数值与随机频率k1和k2的相似度,还原水印图样
        else
            mark_2(i,j)=0;
        end
    end
end
subplot(2,3,5);
mark_2 = uint8(mark_2);
imshow(mark_2,[]),title('提取出的水印');
subplot(2,3,6);
imshow(mark),title('原嵌入水印');
NC=correlation(mark_2,mark);  
disp('原水印图像与提取水印图像互相关系数:')
disp(NC);

function N=correlation(mark_get,mark_prime) 
mark_get=double(mark_get); 
mark_prime=double(mark_prime); 
if size(mark_get)~=size(mark_prime) 
    error('Input vectors must  be the same size!') 
else 
    [m,n]=size(mark_get); 
    fenzi=0; 
    fenmu=0; 
    for i=1:m 
        for j=1:n 
            fenzi=fenzi+mark_get(i,j)*mark_prime(i,j); 
            fenmu=fenmu+mark_prime(i,j)*mark_prime(i,j); 
        end 
    end 
N=min(fenzi/fenmu,fenmu/fenzi); 
end
end

实验效果
1、用图

嵌入图像
在这里插入图片描述

载体图像
在这里插入图片描述
实验结果
在这里插入图片描述
原水印图像与提取水印图像互相关系数:
0.9024

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值