%%
% stdm演算法實現主函式
%%clc;
clear;
close all;
warning off;
d = 200; % 量化步長
type = 1; % 平行投影 2:均勻 3:隨機
%%% vp = ones(8,1); % 均勻投影向量
% vp = vp./sqrt(8);
%% % vp = randn(8,1);
% vp = vp./sqrt(sum(vp.^2)); % 隨機投影向量
%%carrier = imread('lena.bmp');
msg = imread('logo_64.bmp');
carrier = rgb2gray(carrier);
figure(1);
subplot(1,3,1);
imshow(carrier);
title('原始影象');
carrierdct = blkproc(carrier,[8,8],@dct2);
[x,y] = size(carrierdct);
x = x/8;
y = y/8;
carriercellmat = cell(x,y);
vpcellmat = cell(x,y);
for i = 1:x
for j = 1:y
tmpmat = carrierdct((i-1)*8+1:i*8,(j-1)*8+1:j*8);
tmpdiagarray = diag(rot90(tmpmat));
if type == 1 % 平行
value = sum(tmpdiagarray.^2);
vp = tmpdiagarray./sqrt(value); % 平行投影
vpcellmat(i,j) = mat2cell(vp);
elseif type == 2 % 均勻
vp = vp; % 均勻投影向量
else % 隨機
vp = vp; % 隨機投影向量
endvw = stdm_code(d,vp,tmpdiagarray,msg(i,j));
vwdiagmat = diag(vw); % 形成新的對角線元素
tmpmat = rot90(tmpmat); % 旋轉90度 反對角線元素轉移到對角線上
tmpmat = tmpmat - diag(diag(tmpmat)); % 對角線清0
tmpmat = tmpmat + vwdiagmat; % 補全
tmpmat = rot90(tmpmat,3); % 旋轉270度
carriercellmat(i,j) = mat2cell(tmpmat);
endendcarrierdct = cell2mat(carriercellmat);
carrierdct = blkproc(carrierdct,[8,8],@idct2);
carrierdct = uint8(carrierdct);
%%% 透明性誤差(主觀感受)
subplot(1,3,2);
imshow(carrierdct);
title('嵌入水印影象');
%%% 攻擊
carriernoise = imnoise(carrierdct, 'gaussian', 0, 0.01); % 高斯 0.01 0.001
carrierresize = imresize(carrierdct,[1024 1024]); % 縮放
carrierresize = imresize(carrierresize,[512 512]);
%%carrierdct = carriernoise;
% carrierdct = carrierresize;
subplot(1,3,3);
imshow(carrierdct);
title('接收方獲得影象');
% 透明性誤差(psnr)
disp('峰值訊雜比:');
errorx = sum(sum(abs(carrierdct-carrier).^2)); % mse誤差
psnr = 10*log10(255*255/(errorx/512/512)) % psnr 訊雜比
%%% 提取水印
logo = zeros(x,y); % 待提取水印
carrierdct = blkproc(carrierdct,[8,8],@dct2);
for i = 1:x
for j = 1:y
tmpmat = carrierdct((i-1)*8+1:i*8,(j-1)*8+1:j*8);
tmpdiagarray = diag(rot90(tmpmat));
if type == 1 % 平行
vp = cell2mat(vpcellmat(i,j));
logo(i,j) = stdm_decode(d,tmpdiagarray,vp);
elseif type == 2 % 均勻
logo(i,j) = stdm_decode(d,tmpdiagarray,vp);
else % 隨機
logo(i,j) = stdm_decode(d,tmpdiagarray,vp);
endend
end%%
% 穩健性 可視性 logo.bmp
figure(2);
subplot(1,3,1);
imshow(msg,);
title('原始水印影象');
subplot(1,3,2);
imshow(logo,);
title('提取出的影象');
% 1. 直接異或 xor
subplot(1,3,3);
xorlogo = xor(logo,msg);
imshow(xorlogo,);
title('異或後的影象');
% 2. w(:) 矩陣變為列向量
% 水印的相關係數
% w(:)*w'(:)/(sqrt(sum(w(:).^2))*sqrt(sum(w(:).^2)))
disp('相關係數:');
w = logo(:);
w_ = msg(:);
c0 = w'*w_/(sqrt(sum(w.^2))*sqrt(sum(w_.^2)))
warning on;
子函式1:
%%
% qim 嵌入部分
%%function vw = stdm_code(d,vp,vc,v)
p = vp'*vc;
vh = p*vp; % 投影方向向量
vv = vc - vh; % 與投影方向垂直的向量
if v == 0
p_ = q0(p,d); % 需要嵌入0
else
p_ = q1(p,d); % 需要嵌入1
endvh_ = p_*vp; % 投影方向向量
vw = vh_ + vv; % 新的嵌入資訊後的向量
end
子函式2:
%%
% qim 提取部分
%%function value = stdm_decode(d,vw,vp)
p = vp'*vw;
p0 = q0(p,d); % 需要嵌入0
p1 = q1(p,d); % 需要嵌入1
if abs(p0-p) < abs(p1-p)
value = 0;
else
value = 1;
endend
子函式3:
%%
% 隱藏位元0採用的演算法
%%function result = q0(s,d)
result = d*round((s + d/4)/d) - d/4;
end
子函式4:
%%
% 隱藏位元1採用的演算法
%%function result = q1(s,d)
result = d*round((s - d/4)/d) + d/4;
end
數字水印學習教程
目 錄 1 程式介面.5 1.1 程式 5 1.2 執行結果及說明.18 2 空域操作.19 2.1 分層顯示.19 2.1.1 程式 19 2.1.2 執行結果及說明.20 2.2.位值設定.22 2.2.1 實現.22 2.2.2 執行結果及說明.25 2.3.二值化.26 2.3.1 實現.2...
數字水印學習系統
數字水印學習系統v1.0 使用說明書 1.程式介面 1 2.空域操作 1 2.1 分層顯示 1 2.2.位值設定 3 2.3.二值化 4 2.4.sobel邊緣檢測 5 2.5.分塊求均值 6 2.6.元胞自動機 7 2.7.lsb演算法演示 8 2.8.lsb嵌入水印 10 2.9.lsb提取水印...
數字水印學習教程
目 錄 1 程式介面.5 1.1 程式 5 1.2 執行結果及說明.18 2 空域操作.19 2.1 分層顯示.19 2.1.1 程式 19 2.1.2 執行結果及說明.20 2.2.位值設定.22 2.2.1 實現.22 2.2.2 執行結果及說明.25 2.3.二值化.26 2.3.1 實現.2...