STDM 數字水印演算法

2021-07-11 08:14:33 字數 4390 閱讀 4105

%%

% stdm演算法實現主函式

% [email protected]

%%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 嵌入部分

% [email protected]

%%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 提取部分

% [email protected]

%%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採用的演算法

% [email protected]

%%function result = q0(s,d)

result = d*round((s + d/4)/d) - d/4;

end

子函式4:

%%

% 隱藏位元1採用的演算法

% [email protected]

%%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...