MATLAB 水印嵌入函数:wm.m - 详解与代码实现

本文介绍了 MATLAB 中实现水印嵌入功能的函数 wm.m,该函数利用小波变换将水印信息嵌入到图像的特定子带中,并提供了详细的算法解析和代码实现。

1. 函数 wm.m 的实现

function J = wm(I,w,g)
%此函数为嵌入过程
%输入:I为原始图像;w为水印信息;g为水印嵌入的阈值
%输出:J为嵌入水印的图像
%%
%参数设置
step = 0.5; %小波系数增长步长
%%
[mm,nn] = size(I);
%一层小波分解
[LL,LH,HL,HH] = dwt2(I,'haar');
%=======计算avr_LH======
[m0,n0] = size(LH); avr_LH = 0;



%=======计算avr_HL======
[m1,n1] = size(HL); avr_HL = 0;


%判断嵌入的子带
if avr_LH <= avr_HL
    num = 0; loca = LH;
else
    num = 1; loca = HL;
end

%%
%嵌入水印
if num == 0
    loca = wm_type_0(loca,w,step,g);  %LH是横向,写出嵌入子函数
else
    loca = wm_type_1(loca,w,step,g);  %HL是纵向,写出嵌入子函数
end
%%
if num == 0
    LH = loca; 
else
    HL = loca; 
end
J = idwt2(LL,LH,HL,HH,'haar',[mm,nn]);   %小波逆变换,还回原始图像



%以下是辅助函数:

function loca = wm_type_0(loca,w,step,g)
%此函数用于在HL子带嵌入水印
%输入:loca为要嵌入水印的子带
%输出:loca为嵌入水印后的子带

[m2,n2] = size(loca);
index = 1;
%取出2*2的块
for k = 1:2:m2-1
    for kk = 1:2:n2-1
        tem = loca(k:k+1,kk:kk+1);
        a11 = tem(1,1);
        a12 = tem(1,2);
        a21 = tem(2,1);
        a22 = tem(2,2);
        if 0 == w(index)            
            for s = step:step:100*step
                if a11-a12<=g   %如果满足条件,a11增,a21减
                    a11 = a11 + s;
                    a12 = a12 - s;
                else
                    break;     %不满足条件,跳出此循环
                end
            end
            %-----如果a21和a22不满足条件,则也要调整------------
            
            
        end
        if 1 == w(index)            
            for s = step:step:100*step
                if a11-a12>=-g   %如果满足条件,a11增,a21减
                    a11 = a11 - s;
                    a12 = a12 + s;
                else
                    break;     %不满足条件,跳出此循环
                end
            end
             %-----如果a21和a22不满足条件,则也要调整------------
                         
             
             
             
        end
        index = index + 1;        
        tem(1,1) = a11;
        tem(1,2) = a12;
        tem(2,1) = a21;
        tem(2,2) = a22;
        loca(k:k+1,kk:kk+1) = tem;        
    end    
end

function rw = wm_extr_type1(loca)
%脆弱水印中 LH 子带提取水印的代码
[mm,nn] = size(loca);
index = 1;
%取出2*2的块
for k = 1:2:mm-1
    for kk = 1:2:nn-1f
        tem = loca(k:k+1,kk:kk+1);
        a11 = tem(1,1);
        a12 = tem(1,2);
        a21 = tem(2,1);
        a22 = tem(2,2);
        %-------a12+a22 >= a11+a21则水印为0,否则为1-------
        if a12 + a22 >= a11 + a21
            rw(index) = 0;
        else
            rw(index) = 1;
        end
        index = index + 1;
    end    
end
end

### 2. 函数 `wm_type_1.m` 的实现

```matlab
function loca = wm_type_1(loca,w,step,g)
%此函数用于在HL子带嵌入水印
%输入:loca为要嵌入水印的子带
%输出:loca为嵌入水印后的子带

[m2,n2] = size(loca);
index = 1;
%取出2*2的块
for k = 1:2:m2-1
    for kk = 1:2:n2-1
        tem = loca(k:k+1,kk:kk+1);
        a11 = tem(1,1);
        a12 = tem(1,2);
        a21 = tem(2,1);
        a22 = tem(2,2);
        if 0 == w(index)            
            for s = step:step:100*step
                if a12-a22<=g   %如果满足条件,a12增,a22减
                    a12 = a12 + s;
                    a22 = a22 - s;
                else
                    break;     %不满足条件,跳出此循环
                end
            end
            %-----如果a11和a21不满足条件,则也要调整------------
            if a11-a21>=g
                for s = step:step:100*step
                    if a11-a21>=g
                        a11 = a11 - s;
                        a21 = a21 + s;
                    else
                        break;
                    end
                end
            end
            
        end
        if 1 == w(index)            
            for s = step:step:100*step
                if a12-a22>=-g   %如果满足条件,a12减,a22增
                    a12 = a12 - s;
                    a22 = a22 + s;
                else
                    break;     %不满足条件,跳出此循环
                end
            end
             %-----如果a11和a21不满足条件,则也要调整------------
            if a11-a21<=-g
                for s = step:step:100*step
                    if a11-a21<=-g
                        a11 = a11 + s;
                        a21 = a21 - s;
                    else
                        break;
                    end
                end
            end
            
        end
        index = index + 1;        
        tem(1,1) = a11;
        tem(1,2) = a12;
        tem(2,1) = a21;
        tem(2,2) = a22;
        loca(k:k+1,kk:kk+1) = tem;        
    end    
end

end

3. 函数功能说明

wm.m 函数实现将水印信息 w 嵌入到原始图像 I 中,并返回嵌入水印后的图像 J。

  • 该函数首先使用 Haar 小波对图像进行一层分解,得到四个子带 LL、LH、HL 和 HH。
  • 然后根据 LH 和 HL 子带的平均值判断选择哪个子带作为嵌入水印的子带。
  • 接着调用 wm_type_0 或 wm_type_1 函数将水印信息嵌入到选择的子带中。
  • 最后进行小波逆变换,得到嵌入水印后的图像 J。

wm_type_0 和 wm_type_1 函数分别用于在 LH 和 HL 子带中嵌入水印信息。这两个函数的具体实现细节可以参考代码注释。

4. 注意事项

  • 水印信息 w 需要是一个二进制向量,表示水印信息的比特序列。
  • 阈值 g 用于控制水印嵌入的强度,数值越大,嵌入的强度越强,但同时也可能导致图像失真更明显。
  • 该函数实现的是一种脆弱水印算法,即嵌入的水印信息对图像的任何修改都非常敏感。

5. 代码示例

% 加载原始图像
I = imread('lena.bmp');

% 生成水印信息
W = randi([0,1],1,100);

% 设置嵌入阈值
g = 10;

% 嵌入水印
J = wm(I,W,g);

% 保存嵌入水印后的图像
imwrite(J,'watermarked_lena.bmp');

6. 总结

本文介绍了 MATLAB 中实现水印嵌入功能的函数 wm.m,并提供了详细的算法解析和代码实现。该函数利用小波变换将水印信息嵌入到图像的特定子带中,是一种简单的脆弱水印算法。

如果您有任何问题或建议,请在评论区留言。

MATLAB 水印嵌入函数:wm.m - 详解与代码实现

原文地址: https://www.cveoy.top/t/topic/jpxE 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录