基於LSB的圖像數字水印實驗


1. 實驗類別

設計型實驗:MATLAB設計並實現基於LSB的圖像數字水印算法。

2. 實驗目的

了解信息隱藏中最常用的LSB算法的特點,掌握LSB算法原理,設計並實現一種基於圖像的LSB隱藏算法。

 

3. 實驗條件

(1) Windows 2000或Windows Xp以上操作系統;

(2) MATLAB 6.5以上版本軟件;

(3)圖像文件

4. 實驗原理

 基於LSB的圖像數字水印

任何多媒體信息在數字化時都會產生物理隨機噪聲,而人的感官系統對這些隨機噪聲並不敏感。替換技術就是利用這個原理,通過使用秘密信息比特替換隨機噪聲,從而實現信息隱藏目的。圖像高位平面對圖像感官質量起主要作用,去除圖像最低幾個位平面並不會造成畫面質量的下降。利用這個原理可用秘密信息(或稱水印信息)替代載體圖像低位平面以實現信息嵌入。

LSB算法選用最低位平面來嵌入秘密信息,最低位平面對圖像的視覺效果影響最輕微,但很容易受噪聲影響和攻擊,可采用冗余嵌入的方式來增強穩健性加以解決,即在一個區域中嵌入相同的信息,提取時根據該區域中的所有像素判斷。

 

1.嵌入水印.m腳本代碼:

clear all;
clc;
picpath = input('請輸入圖片絕對路徑(加單引號):');
watermark_path = input('請輸入水印文件絕對路徑(加單引號):');
msgfid = fopen(watermark_path,'r');     % 打開秘密文件,讀入秘密信息
[key,count] = fread(msgfid,'ubit1');    % 讀取秘密信息,存入key,count為成功讀入了多少位
fclose(msgfid);                         % 關閉文件
i = imread(picpath);
i1 = i(:,:,1);                          % 提取RGB第1層嵌入水印
[row,col] = size(i1);                   % x行y列
contents = row * col;                   % 圖像能嵌入水印最大比特數
if count > contents
    disp('warning: 當前圖片容量無法通過LSB方法嵌入所有水印信息!按enter退出matlab.');
    pause;
    quit;
else
    disp(['當前圖片通過LSB能嵌入的最大水印比特數為: ',num2str(contents),' bits']);
end
key_counter = 1;
round_counter = 0;
total_watermark_bits = 0;
if mod(count,row) == 0
    round = floor(count/row);
else
    round = floor(count/row) + 1;
end
 
for ii=1:1:round
       for jj = 1:1:row
           i1(jj,ii) = bitset(i1(jj,ii),1,key(key_counter,1));% bitset函數改變像素值最后一位bit為水印bit值
           key_counter = key_counter + 1;
           total_watermark_bits = total_watermark_bits + 1;
           if key_counter > count
               break;
           end
       end  %內層for
       round_counter = round_counter + 1;
       disp(['當前嵌入輪數: ',num2str(round_counter)]);
       if key_counter > count
           disp(['LSB嵌入正常結束!共嵌入水印比特數: ',num2str(total_watermark_bits),' bits']);
           break;
       end
end  %外層for
i(:,:,1) = i1; 
imwrite(i,'E:\new\LSB_watermarked.bmp');
figure;
subplot(1,2,1);
imshow(picpath);
title('原始圖像');
subplot(1,2,2);
imshow(i);
title('LSB嵌入水印后的圖像');

 

運行截圖:

2.提取水印.m腳本代碼:

clear all;
clc;
picpath = input('請輸入待提取LSB水印圖片絕對路徑(加單引號):');
watermark_bits = input('請輸入提取的水印比特數:');
i = imread(picpath);                                   % 讀取含有水印信息的彩色圖像
i1 = i(:,:,1);
key = zeros(watermark_bits,1);                         % 創建一個watermark_bits行1列的全0矩陣,用於存放水印比特
[row,col] = size(i1);   
key_counter = 1;
round = 0;
round_counter = 0;
total_watermark_bits = 0;
if mod(watermark_bits,row) == 0
    round = floor(watermark_bits/row);
else
    round = floor(watermark_bits/row) + 1;
end
for ii = 1:1:round
    for jj = 1:1:row
        key(key_counter,1) = bitget(i1(jj,ii),1);  % 提取圖像矩陣的bit水印信息
        key_counter = key_counter + 1;
        total_watermark_bits = total_watermark_bits + 1;
        if key_counter > watermark_bits
            break;
        end 
    end %內層for
    round_counter = round_counter + 1;
    disp(['當前提取輪數: ',num2str(round_counter)]);
    if key_counter > watermark_bits
        disp(['LSB水印提取正常結束!共提取水印比特數:',num2str(total_watermark_bits),' bits']);
        break;
    end
end %外層for

fobject = fopen('E:\new\LSB_watermark.txt','w');       % 以只寫模式打開一個名為mark_message.txt的文件,不存在則創建之
fwrite(fobject,key,'bit1');               % 將key矩陣中的數作為bit寫入文件句柄為fobject的文件
fclose(fobject);                          % 關閉文件句柄所對應的文件

運行后hidden.txt與LSB_watermark.txt文件水印內容

 

LSB水印實驗的要點

1.該實驗選取的是彩色RGB圖像,是3維圖像,因此要選RGB中的某一層進行水印嵌入,可以選第123層,分別對於R,G,B,本實驗選擇R層及第一層i1 = i(:,:,1)

2.還應對圖像所能容納水印比特最大數進行檢查,以防水印信息太多導致嵌入失敗.

 

3.嵌入完成后,要將選取的RGB層賦給原3維矩陣對應層i(:,:,1) = i1

 

4.代碼注意ifforend配對一個iffor配一個end

上述腳本在matlab6.5能正確運行.

若有不足歡迎指正;若有疑問鄙人也樂於為道友解答,歡迎留言或加QQ群!

 

歡迎加入QQ群:735472015,群內有VC,MFC,win32API,批處理,python學習資料干貨喔👌

 

若您覺得對您有幫助,不妨點個贊👍唄!

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM