簡體   English   中英

將RGB圖像讀取為二進制圖像,並在Matlab中將其顯示為RGB

[英]Read RGB image into binary and display it as RGB in Matlab

這個問題是基於先前提出的一個問題: 通過LSB替代方法了解圖像隱寫術

為了使代碼高效並減少均方誤差(MSE),建議:“按原樣讀取文件,並使用de2bi(fread(fopen(filename)), 8)將其轉換為位。)將這些位嵌入到您的封面圖片所需的最小k因子,可能是1或2。提取秘密時,您將能夠重建原始文件。” 這是我一直在嘗試的方法,但是在某個地方我做錯了,因為沒有得到任何顯示。 但是,MSE確實減少了。 基本上,我對如何將圖像轉換為二進制,對數據執行算法並在提取后顯示圖像感到困惑。

有人可以幫忙嗎?

我已經對您的代碼進行了一些修改,以使其能夠正常工作,無論實際圖像是什么。 但是,它們都必須是彩色或灰度。 您的代碼中還存在一些錯誤,這些錯誤使我無法在我的MATLAB版本上運行它。

首先,您沒有正確讀取圖像。 您正在為圖像打開字節流,然后在字節流上使用imread來讀取圖像。 錯了-只需提供實際文件的路徑即可。

其次,圖像已經在uint8 ,因此您可以對此進行本地的位置換和移位。

除了調整圖像大小外,其余代碼與之前相同。 您無需指定頻道數。 另外, bitcmp出現語法錯誤。 我使用'uint8'代替了值8因為我的MATLAB版本要求您指定期望數據類型的字符串。 這里的值8我假設您的意思是8位,因此在此處放置'uint8'是有意義的。

我還將直接從Stack Overflow中讀取您的圖像。 我假設恐龍圖像是封面,而花是消息:

%%% Change
x = imread('https://i.stack.imgur.com/iod2d.png');         % cover message
y  = imread('https://i.stack.imgur.com/Sg5mr.png');    % message image
n = input('Enter the no of LSB bits to be subsituted- ');

                                     %%% Change
S = uint8(bitor(bitand(x,bitcmp(2^n-1,'uint8')),bitshift(y,n-8))); %Stego
E = uint8(bitand(255,bitshift(S,8-n))); %Extracted

origImg = double(y);   %message image
distImg = double(E);   %extracted image

[M N d] = size(origImg);
distImg1=imresize(distImg,[M N]); % Change

figure(1),imshow(x);title('1.Cover image')
figure(2),imshow(y);title('2.Message to be hide')
figure(3),imshow((abs(S)),[]);title('3.Stegnographic image')
figure(4),imshow(real(E),[]); title('4.Extracted image');

這為我運行,我設法重建消息圖像。 選擇位數大約為4,可以在封面和消息圖像之間做出很好的折衷。

加載字節流而不是密鑰的像素數組將導致較小的有效負載。 它的大小取決於圖像格式以及顏色的重復性。

如果該文件名是有效的圖像文件,則imread()需要文件名並加載像素數組。 加載文件的字節流並將其傳遞給imread()沒有任何意義。 你想要的是這個

% read in the byte stream of a file
fileID = fopen(filename);
secretBytes = fread(fileID);
fclose(fileID);

% write it back to a file
fileID = fopen(filename);
fwrite(fileID, secretBytes);
fclose(fileID);

請注意,封面圖像會以像素陣列的形式加載,因為您需要對其進行修改。

有效載荷的大小為length(secretBytes) * 8 ,這必須適合您的封面圖像。 如果您決定為每個像素嵌入k位,則對於您的所有彩色平面,必須滿足以下要求

secretBytes * 8 <= prod(size(coverImage)) * k

如果您只想嵌入一個顏色平面,而不論您的封面介質是RGB還是灰度,都需要對其進行修改,以

secretBytes * 8 <= size(coverImage,1) * size(coverImage,2) * k

如果不滿足此要求,則可以選擇

  • 停止進程
  • 要求用戶嵌入一個較小的文件
  • 增加k
  • 包括更多顏色平面(如果有)

以下是僅在最低有效位(k = 1)中嵌入一個顏色平面的原型。

HEADER_LEN = 24;

coverImage = imread('lena.png');
secretBytes = uint8('Hello world'); % this could be any byte stream

%% EMBEDDING
coverPlane = coverImage(:,:,1);     % this assumes an RGB image
bits = de2bi(secretBytes,8)';
bits = [de2bi(numel(bits), HEADER_LEN) bits(:)'];
nBits = length(bits);
coverPlane(1:nBits) = bitset(coverPlane(1:nBits),1,bits);
coverImage(:,:,1) = coverPlane;

%% EXTRACTION
nBits = bi2de(bitget(coverPlane(1:HEADER_LEN),1));
extBits = bitget(coverPlane(HEADER_LEN+1:HEADER_LEN+nBits),1);
extractedBytes = bi2de(reshape(extBits',8,length(extBits)/8)')';

除了消息字節以外,還必須嵌入密鑰的長度,因此提取器知道要提取多少位。

如果將k> 1嵌入或在多個顏色平面中嵌入,則邏輯會變得更加復雜,並且必須注意如何實現更改。

例如,您可以選擇一次嵌入每個顏色平面,直到用完所有要隱藏的位為止,或者可以使用coverImage(:)展平整個像素陣列,該圖像將嵌入每個像素的RGB中,一個像素一次直到您用完所有位。

如果嵌入k> 1,則必須用0填充bits向量,直到其長度可被k整除。 然后,您可以將k個組中的位合並為

bits = bi2de(reshape(a',k,length(bits)/k)')';

要嵌入它們,您想返回使用bitand()bitor()

coverPlane(1:nBits) = bitor(bitand(coverPlane(1:nBits), bitcmp(2^k-1,'uint8')), bits);

還有更多細節,例如准確地提取24位消息長度,我不得不強調,您必須非常仔細地考慮如何實現所有這些內容。 您不能只是縫合來自不同代碼段的部件,並期望一切都能做您想要的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM