Matlab-LSB資訊隱藏實驗
阿新 • • 發佈:2019-02-10
一、實驗內容
實驗完成形式:
用MATLAB函式實現LSB資訊隱藏和提取
實驗選擇載體:
512×512灰度影象
實驗效果和分析:
1.完成基本的LSB資訊隱藏及提取
2.能隨機選擇嵌入位進行資訊隱藏及提取(考慮安全性因素)
3.能夠計算PSNR,分析資訊隱藏影象質量
4.完成對祕密資訊的影象載體進行攻擊,採用的攻擊方法: jpeg壓縮,resize縮放
5.計算每種攻擊方法提取的祕密資訊誤位元速率
二、實驗涉及到的相關演算法
1.基本LSB資訊隱藏及提取演算法——影象的第一層是LSB層,替換後對原影象的影響較小,第8層為MSB層對原影象影響較大。1)讀入影象載體:gray=imread('lena_gray.bmp');
2)讀入要隱藏的影象,並轉換為二進位制:woman=imread('woman_rgb.bmp'); woman_to_binary=im2bw(woman);
3)在影象載體的第一層隱藏影象:gray_set=bitset(gray,1,woman_to_binary);
4)提取隱藏的影象:gray_get_1=bitget(gray_set,1);
演算法實現原始碼:
gray=imread('lena_gray.bmp'); gray_8=bitget(gray,8); gray_6=bitget(gray,6); gray_7=bitget(gray,7); woman=imread('woman_rgb.bmp'); woman_to_binary=im2bw(woman); gray_set=bitset(gray,1,woman_to_binary); gray_set_8=bitset(gray,8,woman_to_binary); gray_get_8=bitget(gray_set_8,8); gray_get_1=bitget(gray_set,1); subplot(221),imshow(gray),title('原始影象'); subplot(222),imshow(logical(gray_8)),title('原始影象的第8層'); subplot(223),imshow(gray_set_8),title('在第8層隱藏資訊後'); subplot(224),imshow(logical(gray_get_8)),title('獲取隱藏的影象'); figure,%新開啟一個視窗 subplot(221),imshow(gray),title('原始影象'); subplot(222),imshow(woman_to_binary),title('要隱藏的影象'); subplot(223),imshow(gray_set),title('在第1層隱藏資訊後'); subplot(224),imshow(logical(gray_get_1)),title('獲取隱藏的影象');
2.完成隨機選擇嵌入位進行LSB資訊隱藏及提取演算法。
隨機選擇嵌入位,嵌入水印資訊,input為載體影象,file為要嵌入的文字檔案,output為嵌入水印後的影象,key為隨機數種子。
%2.隨機選擇嵌入位 function [ste_cover,len_total]=rand_lsb_hide(input,file,output,key) %讀入影象矩陣 cover=imread(input); ste_cover=cover; ste_cover=double(ste_cover); %將文字檔案轉換為二進位制 f_id=fopen(file,'r'); [msg,len_total]=fread(f_id,'ubit1'); %判斷嵌入的資訊量是否過大 [m,n]=size(ste_cover); if len_total>m*n error('嵌入資訊量過大,請重新選擇影象'); end %p作為訊息嵌入位計數器 p=1; %呼叫隨機間隔函式選取畫素點 [row,col]=randinterval(ste_cover,len_total,key); %在LSB隱藏資訊 for i=1:len_total ste_cover(row(i),col(i))=ste_cover(row(i),col(i))-mod(ste_cover(row(i),col(i)),2)+msg(p,1); if p==len_total break; end p=p+1; end ste_cover=uint8(ste_cover); imwrite(ste_cover,output); %顯示實驗結果 subplot(1,2,1);imshow(cover);title('原始影象'); subplot(1,2,2);imshow(output);title('隱藏資訊的影象');
實現效果:
讀取嵌入的水印資訊,output為嵌入水印後的影象,goalfile為提取出的水印檔案,key與嵌入水印時的值相同:
function result = rand_lsb_get(output,len_total,goalfile,key)
ste_cover=imread(output);
ste_cover=double(ste_cover);
%判斷嵌入資訊量是否過大
[m,n]=size(ste_cover);
if len_total>m*n
error('嵌入資訊量過大,請重新選擇影象');
end
frr=fopen(goalfile,'a');
%p作為訊息嵌入位計數器,將訊息序列寫回文字檔案
p=1;
%呼叫隨機間隔函式選取畫素點
[row,col]=randinterval(ste_cover,len_total,key);
for i=1 :len_total
if bitand(ste_cover(row(i),col(i)),1)==1
fwrite(frr,1,'ubit1');
result(p,1)=1;
else
fwrite(frr,0,'ubit1');
result(p,1)=0;
end
if p ==len_total
break;
end
p=p+1;
end
fclose(frr);
隨機數生成演算法:
%書上50頁
function [row,col]=randinterval(matrix,count,key)
%計算間隔的位數
[m,n]=size(matrix);
interval1=floor(m*n/count)+1;
interval2=interval1-2;
if interval2==0
error('載體太小,不能將私密資訊隱藏進去');
end
%生成隨機序列
rand('seed',key);
a=rand(1,count);
%初始化
row=zeros([1 count]);
col=zeros([1 count]);
%計算row,col
r=1;
c=1;
row(1,1)=r;
col(1,1)=c;
for i=2:count
if a(i)>=0.5
c=c+interval1;
else
c=c+interval2;
end
if c>n
r=r+1;
if r>m
error('載體太小,不能私密資訊隱藏進去');
end
c=mod(c,n);
if c==0
c=1;
end
end
row(1,i)=r;
col(1,i)=c;
end
3.計算誤位元速率的演算法——分別對含有祕密資訊的影象載體進行攻擊,攻擊方式為jpeg壓縮,resize縮放,根據不同的壓縮比例,縮放比例的分別計算誤位元速率並顯示如下:
這部分程式碼是參考別人的部落格編寫的:https://blog.csdn.net/cheeseandcake/article/details/52997903?locationNum=11&fps=1
function ber_resize=calcute_resize_ber(input,messagefile,len_total,key)
for resize =0.5:1:10
%讀取已經隱藏資訊的影象。
fp=imread(input);
%使用 imresize 函式對影象進行縮放,設定縮放比例。
output=imresize(fp,resize,'bicubic'); %利用雙三次插值方法將 Ifp放大 size 倍
intchanged=double(output);
%p作為訊息嵌入位計數器,將訊息序列寫回文字檔案
p=1;
%呼叫隨機間隔函式選取畫素點
[row,col]=randinterval(intchanged,len_total,key);
for i=1 :len_total
if bitand(intchanged(row(i),col(i)),1)==1
result(p,1)=1;
else
result(p,1)=0;
end
if p ==len_total
break;
end
p=p+1;
end
%讀取原檔案,即隱藏的資訊,以二進位制讀取。並取得訊息長度
message=fopen(messagefile,'r');
%按位以二進位制形式讀取文字內容與長度
[msg,len_total]=fread(message,'ubit1');
%比較取得的資訊和原資訊的每一位,記錄不相等位數的個數。
bit_error=find(result~=msg); %尋找不相等的位置
bit_error_count=size(bit_error,1); %統計不相等的個數
%用不相等個數除以總長度即可得到誤位元速率ber
ber_resize(resize+0.5)=bit_error_count/len_total;
end
% plot引數說明:
% 引數1是橫座標自變數,引數2是縱座標自變數,引數3是指用說明形式描點,引數4和5代表把散點連結起來
resize=0.5:1:10;
plot(resize,ber_resize,'*',resize,ber_resize);
title('基於圖片縮放質量的誤位元速率圖表');
function ber_jpeg=calcute_jpeg_ber(input,output,messagefile,len_total,key)
for compressibility=10:10:100
%Compressiblity是影象的質量因子,可設定在0-100範圍內
%compressibility=90;
%讀取已經隱藏資訊的影象。
fp=imread(input);
%使用 imwrite 函式對影象進行壓縮,設定壓縮比例。
imwrite(fp,output,'quality',compressibility);
intchanged=imread(output);
intchanged=double(intchanged);
%p作為訊息嵌入位計數器,將訊息序列寫回文字檔案
p=1;
%呼叫隨機間隔函式選取畫素點
[row,col]=randinterval(intchanged,len_total,key);
for i=1 :len_total
if bitand(intchanged(row(i),col(i)),1)==1
result(p,1)=1;
else
result(p,1)=0;
end
if p ==len_total
break;
end
p=p+1;
end
%讀取原檔案,即隱藏的資訊,以二進位制讀取。並取得訊息長度
message=fopen(messagefile,'r');
%按位以二進位制形式讀取文字內容與長度
[msg,len_total]=fread(message,'ubit1');
%比較取得的資訊和原資訊的每一位,記錄不相等位數的個數。
bit_error=find(result~=msg); %尋找不相等的位置
bit_error_count=size(bit_error,1); %統計不相等的個數
%用不相等個數除以總長度即可得到誤位元速率ber
ber_jpeg(compressibility/10)=bit_error_count/len_total;
end
% plot引數說明:
% 引數1是橫座標自變數,引數2是縱座標自變數,引數3是指用說明形式描點,引數4和5代表把散點連結起來
compressibility=10:10:100;
plot(compressibility,ber_jpeg,'*',compressibility,ber_jpeg);
title('基於圖片壓縮質量因子的誤位元速率圖表');
4.計算水印相關係數PSNR——PSNR值越大,影象質量越好:
function PSNR=calcute_psnr(input,inputchange)
img=imread(input);
[h,w]=size(img);
%imgn=imresize(img,[floor(h/2) floor(w/2)]);
%imgn=imresize(imgn,[h w]);
imgn=imread(inputchange);
img=double(img);
imgn=double(imgn);
%編碼一個畫素用多少二進位制位
B=8;
%影象有多少灰度級
MAX=2^B-1;
MES=sum(sum((img-imgn).^2))/(h*w); %均方差
PSNR=20*log10(MAX/sqrt(MES)); %峰值信噪比