設計型實驗:MATLAB設計並實現基於LSB的圖像數字水印算法。python
瞭解信息隱藏中最經常使用的LSB算法的特色,掌握LSB算法原理,設計並實現一種基於圖像的LSB隱藏算法。算法
(1) Windows 2000或Windows Xp以上操做系統;函數
(2) MATLAB 6.5以上版本軟件;學習
(3)圖像文件ui
基於LSB的圖像數字水印spa
任何多媒體信息在數字化時都會產生物理隨機噪聲,而人的感官系統對這些隨機噪聲並不敏感。替換技術就是利用這個原理,經過使用祕密信息比特替換隨機噪聲,從而實現信息隱藏目的。圖像高位平面對圖像感官質量起主要做用,去除圖像最低幾個位平面並不會形成畫面質量的降低。利用這個原理可用祕密信息(或稱水印信息)替代載體圖像低位平面以實現信息嵌入。操作系統
LSB算法選用最低位平面來嵌入祕密信息,最低位平面對圖像的視覺效果影響最輕微,但很容易受噪聲影響和攻擊,可採用冗餘嵌入的方式來加強穩健性加以解決,即在一個區域中嵌入相同的信息,提取時根據該區域中的全部像素判斷。設計
1.嵌入水印.m腳本代碼:code
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嵌入水印後的圖像');
運行截圖:blog
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中的某一層進行水印嵌入,能夠選第1,2或3層,分別對於R,G,B層,本實驗選擇R層及第一層i1 = i(:,:,1)
2.還應對圖像所能容納水印比特最大數進行檢查,以防水印信息太多致使嵌入失敗.
3.嵌入完成後,要將選取的RGB層賦給原3維矩陣對應層i(:,:,1) = i1
4.代碼注意if及for與end配對,一個if或for配一個end
上述腳本在matlab6.5能正確運行.
如有不足歡迎指正;如有疑問鄙人也樂於爲道友解答,歡迎留言或加QQ羣!
歡迎加入QQ羣:735472015,羣內有VC,MFC,win32API,批處理,python學習資料乾貨喔👌
若您以爲對您有幫助,不妨點個贊👍唄!