基于小波变换的双彩色数字水印算法

本文章的算法思路来自文章《彩色数字水印技术研究》,文章大体思路是对RGB宿主图像转换为HSV色彩空间后对三个通道分别做三级小波变换,水印图像的RGB三个通道数值归一化到[-1,1]后,乘以一个权重系数,分别整合到宿主图像HSV三个通道上,整合原则是优先选取低频分量,低频分量中优先选取系数大的,这样对宿主图像的视觉影响比较小。提取水印则是逆过程。

本次在MATLAB 2014b实现,由于水印图像尺寸比较大,三级小波的低频分量位置不够,所以只进行了一级小波变换。

输入宿主图像为512*512*3的RGB,格式为uint8,水印图像为140*200*3的RGB,格式为uint8

function [MarkedImg] = Hide_3(OriImg,Print) 

%  功能   将Print中的携带的信息通过图像处理技术隐藏在OriImg中 
% OriImg  输入参数,RGB彩色图像,uint8格式,大小为512*512*3,作为隐
% 藏信息的载体 
% Print   输入参数,RGB彩色图像,uint8格式,大小为140*200*3,信息本
% 身所在 
% MarkedImg  输出参数,RGB彩色图像,uint8格式,大小为512*512*3,经过
% 信息隐藏处理后的图像 

%OriImg = imread('I2.jpg');
%Print = imread('m5.jpg');
OriImg = rgb2hsv(OriImg);

vlayer = OriImg(:,:,3);
vvalue = sum(sum(vlayer));
if vvalue > 2e5
    alpha = 0.04;
elseif vvalue<1.5e5
    alpha = 0.1;
else
    alpha = 0.2;
end

MarkedImg = zeros(size(OriImg));

for i=1:3
    Orilayer = OriImg(:,:,i);
    Printlayer = Print(:,:,i);
    Printlayer = (double(Printlayer)-128)/128;  %归一到-1~1
    
    [C,S] = wavedec2(Orilayer,1,'db2');

    [rows, cols] = size(Printlayer);
    totallength = rows*cols;
    cA1 = appcoef2(C,S,'db2',1);
    [cA1_r, cA1_c] = size(cA1);

    part1length = cA1_r*cA1_c;
    cA1 = C(1:part1length);
    [~, IA] = sort(abs(cA1),'descend');
    IA = IA(1:totallength);

    flattenpri = reshape(Printlayer, 1, []);
    C(IA) = C(IA)+alpha*flattenpri;
    
    Outlayer = waverec2(C,S,'db2');
    MarkedImg(:,:,i) = Outlayer;

end



Imgout = hsv2rgb(MarkedImg);
MarkedImg = im2uint8(Imgout);
imshow(MarkedImg);
end


function [Print] = Recover_3(MarkedImg, Rect, OriImg) 

rec_row = Rect(2,1);
rec_col = Rect(2,2);

%OriImg = imread('I2.jpg');
OriImg = rgb2hsv(OriImg);
%MarkedImg = imread('testhid1.jpg');

MarkedImg = rgb2hsv(MarkedImg);
Print = zeros(rec_row, rec_col, 3);
vlayer = OriImg(:,:,3);
vvalue = sum(sum(vlayer));
if vvalue > 2e5
    alpha = 0.04;
elseif vvalue<1.5e5
    alpha = 0.1;
else
    alpha = 0.2;
end
for i=1:3
    Orilayer = OriImg(:,:,i);
    Marklayer = MarkedImg(:,:,i);
    [Co,So] = wavedec2(Orilayer,1,'db2');
    coA1 = appcoef2(Co,So,'db2',1);
    [cA1_r, cA1_c] = size(coA1);
    part1length = cA1_r*cA1_c;
    coA1 = Co(1:part1length);
    
    [~, IAo] = sort(abs(coA1),'descend');
    IAo = IAo(1:rec_row*rec_col);
    
    [Cm,~] = wavedec2(Marklayer,1,'db2');
    cmA1 = Cm(1:part1length);
    

    flat_print = cmA1(IAo)-coA1(IAo);

    Print_layer = reshape(flat_print, rec_row, rec_col)/alpha;
    Print_layer = (Print_layer*128)+128;
    Print(:,:,i) = Print_layer;
end
Print = uint8(Print);
figure(2)
imshow(Print);
end
    

实现效果:

OriImg

基于小波变换的双彩色数字水印算法_第1张图片


加入水印



水印图片

基于小波变换的双彩色数字水印算法_第2张图片


恢复出来的水印图片

基于小波变换的双彩色数字水印算法_第3张图片

实验证明,在经过中值滤波和JPG压缩后,水印依然有一定辨识能力

你可能感兴趣的:(数字水印)