使用Matlab进行图像隐写:检索隐藏的图像

时间:2014-04-18 00:47:38

标签: matlab steganography

任何人都可以帮我弄清楚为什么我的代码只生成一半的图像并在提取隐藏的图像后切断另一半。一半图像显示,另一半完全变黑。似乎无法弄明白。

I2 = imread('c:/df/img/Lena1.png');
output_stream="";
data_size_s="";     %In bytes and as a string  

%We read the size of the target from the stego image (first 16 bits)
k=1;
for i=1:rows(I2)
  for j=1:columns(I2)
    if (k<18) s=dec2bin(double(I2(i,j,1)),8); data_size_s=strcat(data_size_s,s(8)); k++; endif
    if (k<18) s=dec2bin(double(I2(i,j,2)),8); data_size_s=strcat(data_size_s,s(8)); k++; endif
    if (k<18) s=dec2bin(double(I2(i,j,3)),8); data_size_s=strcat(data_size_s,s(8)); k++; endif
 end
end

%We pass the size of the target image from string to integer
target_rows=uint32(bin2dec(substr(data_size_s, 1,8)));   
target_columns=uint32(bin2dec(substr(data_size_s,9,8))); 
data_size_int=target_rows*target_columns;  % Data Size in bytes as integer


%We read the output_stream from the stego image
total_data_size=(8*data_size_int)+17;    % Total length of the output stream (header + target data)

k=1;
for i=1:rows(I2)
  for j=1:columns(I2)
    if (k<=(total_data_size)) s=dec2bin(double(I2(i,j,1)),8); output_stream=strcat(output_stream,s(8)); k++; endif
    if (k<=(total_data_size)) s=dec2bin(double(I2(i,j,2)),8); output_stream=strcat(output_stream,s(8)); k++; endif
    if (k<=(total_data_size)) s=dec2bin(double(I2(i,j,3)),8); output_stream=strcat(output_stream,s(8)); k++; endif
  end
end

I3_rows=uint32(bin2dec(substr(output_stream,1,8)));
I3_columns=uint32(bin2dec(substr(output_stream,9,8)));
k=18;


 I3=uint8(zeros(I3_rows,I3_columns,3));     % We create a empty image with the  dimensions of the target
 total_data_size=(8*data_size_int)+17;
  for i=1:I3_rows
    for j=1:I3_columns
      if (k<=total_data_size) I3(i,j,1)=uint8(bin2dec(substr(output_stream,k,8))); k=k+8; endif
      if (k<=total_data_size) I3(i,j,2)=uint8(bin2dec(substr(output_stream,k,8))); k=k+8; endif
      if (k<=total_data_size) I3(i,j,3)=uint8(bin2dec(substr(output_stream,k,8))); k=k+8;     endif

  end
 end

 %We show the hidden image.
 imshow(I3);

1 个答案:

答案 0 :(得分:0)

您提供的信息不足以解决问题,因此根据您过去的问题以及您在其他论坛上发布的类似问题,这个答案是有根据的猜测。

在你的previous question中,原始编辑有一个算法可以提取像素流,然后根据目标图像行和列将它们转换为灰度图像大小。然后,你问你如何提取彩色图像,我告诉你它是由3个颜色平面组成的,灰度图像只由一个组成。所以你必须隐藏然后提取所有这些。

我的结论基于Mathworks上发布的this question,其结果不正确。对于该结果有两种可能的解释,它们实际上是同一种。

第一种可能性

您只修改了提取算法以获取提取的流并将其转换为彩色图像,而嵌入的秘密仍然是灰度图像。灰度图像的信息比彩色图像少3倍。你错误地试图将提取的流放在一个彩色图像中,并且你的像素耗尽了1/3,所以其余部分保持不变(黑色)。

第二种可能性

你实际上已经嵌入了一个彩色图像,一个平面接着另一个。但是,在提取隐藏图像的大小时,您执行了rows * columns * 8,它为您提供了一个平面像素的位数。由于您忘记将它复数为3,因此您只提取了第一个平面。现在你有了与上面相同的情况,你已经提取了一个颜色平面,并尝试将像素放在图像的前三分之一的所有三个平面中。

底线

确保您的提取过程与嵌入过程完全相反。在关于Mathworks的问题中,您说这是针对项目而您没有隐藏算法。然而,分配该项目的人应该告诉你他隐藏秘密的步骤。如果隐藏图像是灰度图像,则无法重建彩色图像。如果隐藏的图像确实是彩色图像,则必须提取所有颜色平面并按正确的顺序将它们放在一起。假设在输出流中,您首先获得红色平面的所有数据,然后是绿色数据,然后是蓝色数据,以下代码snipet将重建您的图像。

I3=uint8(zeros(I3_rows,I3_columns,3));  % Initialise reconstructed image
k=18;                                   % Starting point in the stream, red plane
green=8*data_size_int;                  % Offset for green plane in the stream
blue=2*green;                           % Offset for blue plane in the stream
for i=1:I3_rows
    for j=1:I3_columns
        I3(i,j,1)=uint8(bin2dec(substr(output_stream,k,8)));
        I3(i,j,2)=uint8(bin2dec(substr(output_stream,k+green,8)));
        I3(i,j,3)=uint8(bin2dec(substr(output_stream,k+blue,8)));
        k=k+8;
    end
end

不要忘记彩色图像的流的总大小应为

total_data_size=(3*8*data_size_int)+17;