目录
DWT-DCT-SVD彩色图像水印技术是一种综合了离散小波变换(DWT)、离散余弦变换(DCT)和奇异值分解(SVD)的方法。以下是对其原理的详细介绍:
1. 离散小波变换(DWT)
离散小波变换(Discrete Wavelet Transform,DWT)是对连续小波变换的尺度、位移按照2的幂次进行离散化得到的,所以也称之为二进制小波变换。它经常用于小波分析中的近似与细节表示,其中近似表示信号的高尺度,即低频信息;细节表示信号的高尺度,即高频信息。对于含有噪声的信号,噪声分量的主要能量集中在小波解的细节分量中。在数字图像处理中,需要将连续的小波及其小波变换离散化,这也是一般计算机实现中使用二进制离散处理的原因。
DWT用于图像的多尺度分解。它可以将图像分解为多个频率子带,这些子带可以表示图像的不同细节和近似信息。对于二维图像(I(x, y)),其二维DWT可以表示为:
2. 离散余弦变换(DCT)
离散余弦变换(Discrete Cosine Transform,DCT)是与傅里叶变换相关的一种变换,类似于离散傅里叶变换(DFT for Discrete Fourier Transform),但是只使用实数。离散余弦变换相当于一个长度大概是它两倍的离散傅里叶变换,这个离散傅里叶变换是对一个实偶函数进行的(因为一个实偶函数的傅里叶变换仍然是一个实偶函数),在有些变形里面需要将输入或者输出的位置移动半个单位。
DCT是在实数域中的变换,用于将信号或图像从空间域转换到频率域。对于(8 \times 8)的图像块(B(x,y)),其DCT可以表示为:
3. 奇异值分解(SVD)
SVD是一种在线性代数中常用的方法,可以用于图像的分解和重构。对于任意实数矩阵(A),其SVD可以表示为:
[A = U\Sigma V^T]
其中,(U)和(V)是正交矩阵,而(\Sigma)是对角矩阵,对角线上的元素是(A)的奇异值。
4. 水印嵌入
对原始图像进行DWT分解,得到近似和细节子带。然后,在选定的子带上进行DCT变换。接着,对DCT系数进行SVD分解。水印信息可以通过修改SVD的奇异值来嵌入。最后,通过逆SVD、逆DCT和逆DWT得到含水印的图像。
5. 水印提取
水印提取是水印嵌入的逆过程。首先,对含水印的图像进行DWT、DCT和SVD变换。然后,从修改的奇异值中提取水印信息。最后,通过相应的逆变换得到提取的水印图像。
6. 仿真测试
clc;
clear;
close all;
warning off;
addpath(genpath(pwd));
Image=imread('lena.png');
Water=imread('water.png');
%嵌入水印
[Iwm,Uw,Vw]=EmbedWatermark(Image,Water);
%加入攻击方式
%JPEG2000攻击
Iwm1 = JPEG2000Attack(Iwm,90);
%JPEG攻击
Iwm2 = JPEGAttack(Iwm,90);
%噪声攻击
Iwm3 = noiseAttack(Iwm,3);
%滤波攻击
Iwm4 = FilterAttack(Iwm,3);
%整形攻击
Iwm5 = SharpenAttack(Iwm);
%均衡攻击
Iwm6 = histeqAttack(Iwm);
%旋转攻击
Iwm7 = RotationAttack(Iwm);
figure(2)
subplot(241);
imshow(uint8(Iwm1))
title('JPEG2000攻击');
subplot(242);
imshow(uint8(Iwm2))
title('JPEG攻击');
subplot(243);
imshow(uint8(Iwm3))
title('噪声攻击');
subplot(244);
imshow(uint8(Iwm4))
title('滤波攻击');
subplot(245);
imshow(uint8(Iwm5))
title('整形攻击');
subplot(246);
imshow(uint8(Iwm6))
title('均衡攻击');
subplot(247);
imshow(uint8(Iwm7))
title('旋转攻击');
figure(1)
imshow(uint8(Iwm))
title('嵌入水印图像');
figure(3)
subplot(241);
[WaterR,WaterG,WaterB]=ExtractWatermark(Iwm1,Image,Uw,Vw,Water);
NCR=ncc(uint8(WaterR),Water);
NCG=ncc(uint8(WaterG),Water);
NCB=ncc(uint8(WaterB),Water);
a=[NCR,NCG,NCB];
[m,p]=max(a)
if p==1
imshow(uint8(WaterR))
elseif p==2
imshow(uint8(WaterG))
else
imshow(uint8(WaterB))
end
title('JPEG2000攻击提取水印');
subplot(242);
[WaterR,WaterG,WaterB]=ExtractWatermark(Iwm2,Image,Uw,Vw,Water);
NCR=ncc(uint8(WaterR),Water);
NCG=ncc(uint8(WaterG),Water);
NCB=ncc(uint8(WaterB),Water);
a=[NCR,NCG,NCB];
[m,p]=max(a)
if p==1
imshow(uint8(WaterR))
elseif p==2
imshow(uint8(WaterG))
else
imshow(uint8(WaterB))
end
title('JPEG攻击提取水印');
subplot(243);
[WaterR,WaterG,WaterB]=ExtractWatermark(Iwm3,Image,Uw,Vw,Water);
NCR=ncc(uint8(WaterR),Water);
NCG=ncc(uint8(WaterG),Water);
NCB=ncc(uint8(WaterB),Water);
a=[NCR,NCG,NCB];
[m,p]=max(a)
if p==1
imshow(uint8(WaterR))
elseif p==2
imshow(uint8(WaterG))
else
imshow(uint8(WaterB))
end
title('噪声攻击提取水印');
subplot(244);
[WaterR,WaterG,WaterB]=ExtractWatermark(Iwm4,Image,Uw,Vw,Water);
NCR=ncc(uint8(WaterR),Water);
NCG=ncc(uint8(WaterG),Water);
NCB=ncc(uint8(WaterB),Water);
a=[NCR,NCG,NCB];
[m,p]=max(a)
if p==1
imshow(uint8(WaterR))
elseif p==2
imshow(uint8(WaterG))
else
imshow(uint8(WaterB))
end
title('滤波攻击提取水印');
subplot(245);
[WaterR,WaterG,WaterB]=ExtractWatermark(Iwm5,Image,Uw,Vw,Water);
NCR=ncc(uint8(WaterR),Water);
NCG=ncc(uint8(WaterG),Water);
NCB=ncc(uint8(WaterB),Water);
a=[NCR,NCG,NCB];
[m,p]=max(a)
if p==1
imshow(uint8(WaterR))
elseif p==2
imshow(uint8(WaterG))
else
imshow(uint8(WaterB))
end
title('整形攻击提取水印');
subplot(246);
[WaterR,WaterG,WaterB]=ExtractWatermark(Iwm6,Image,Uw,Vw,Water);
NCR=ncc(uint8(WaterR),Water);
NCG=ncc(uint8(WaterG),Water);
NCB=ncc(uint8(WaterB),Water);
a=[NCR,NCG,NCB];
[m,p]=max(a)
if p==1
imshow(uint8(WaterR))
elseif p==2
imshow(uint8(WaterG))
else
imshow(uint8(WaterB))
end
title('均衡攻击提取水印');
subplot(247);
[WaterR,WaterG,WaterB]=ExtractWatermark(Iwm7,Image,Uw,Vw,Water);
NCR=ncc(uint8(WaterR),Water);
NCG=ncc(uint8(WaterG),Water);
NCB=ncc(uint8(WaterB),Water);
a=[NCR,NCG,NCB];
[m,p]=max(a)
if p==1
imshow(uint8(WaterR))
elseif p==2
imshow(uint8(WaterG))
else
imshow(uint8(WaterB))
end
title('旋转攻击提取水印');