I am confused with the Peak signal-to-noise ratio (PSNR) between original image and encrypted image. As i know, the higher PSNR value means the better image quality. I tried to test and calculate the PSNR value. I used LSB technique on the text steganography.
Now, what I think in my mind is:
Should more character embed into image, produce less PSNR value, or less character embed into image, produce high PSNR value?
More character embed, means more manipulation on the pixel. So, PSNR value become lesser?
Anyone can tell me or correct me with my mistake?
------Attached Coding------
Str = 'after this, I tried calculate the PSNR value with original image and stego image. 100 character which is read from file is embedded into image, higher PSNR value. 5 character, less PSNR value.';%many character
%Str = 'a'; %one character
Str=uint8(Str); %converting to 8 bit numbers for proper calculation
fprintf('%d ', Str);
fprintf('\n');
stringLength = length(Str);
x=imread('lena.bmp'); %reading the image file
x=uint8(x); %conversion to 8 bit
[x_row,x_col]=size(x);
numPixelsInImage = numel(x);
bitsPerLetter = 7; % For ASCII, this is 7.
numPixelsNeededForString = stringLength * bitsPerLetter;
binaryAsciiString = dec2bin(Str)'
whos binaryAsciiString
binaryAsciiString = binaryAsciiString(:)'
stegoImage = x;
stegoImage(1:numPixelsInImage) = bitset(stegoImage(1:numPixelsInImage), 1, 0);
oneIndexes = find(binaryAsciiString == '1');
stegoImage(oneIndexes) = bitset(stegoImage(oneIndexes), 1, 1);
imwrite(uint8(stegoImage),'stego123.bmp')
fprintf('\nPSNR: %9.7f dB\n\n', psnr(x,stegoImage));
After this, I tried calculate the PSNR value with original image and stego image. 100 character which is read from file is embedded into image, higher PSNR value. 5 character, less PSNR value.
That's why I get confused.
---HERE is my PSNR code---
function [PSNR,mse]=psnr(X,Y)
% function [PSNR,mse]=psnr(X,Y)
% Peak signal to noise ratio of the difference between images and the
%mean square error
% If the second input Y is missing then the PSNR and MSE of X itself
% becomes the output (as if Y=0).
if nargin<2, D=X;
else
if any(size(X)~=size(Y)), error('The input size is not equal to each other!'); end
D=X-Y;
end
mse=sum(D(:).*D(:))/prod(size(X));
PSNR=10*log10(255^2/mse);
I just call the function of PSNR and print the PSNR value of original image and stego image.
The many character I embed, I get 51.1687256 dB. The one character I embed, I get 51.1578686 dB.
Can tell me why?
There is an error in your pnsr
function. Both inputs are uint8
, which restricts all values in the 0-255 range. This can be a problem for D=X-Y
.
>> uint8(0) - uint8(1)
0
>> double(0) - double(1)
-1
Changing to D = double(X) - double(Y)
will give you the correct values for the long and 1-letter strings, 51.1576 dB and 51.1578 dB respectively.
However, your algorithm is suboptimal. You set the LSB of every pixel to 0 before embedding your bits. You effectively modify up to 262144 pixels while your message is much shorter. This brings down the PSNR by a lot and explains why the value is so similar for messages of both 7 and 1536 bits long. Instead, you should modify only the minimum number of pixels required for embedding your message by using numPixelsNeededForString
. Or more compactly,
cover = imread('lena512.png');
Str = 'after this, I tried calculate the PSNR value with original image and stego image. 100 character which is read from file is embedded into image, higher PSNR value. 5 character, less PSNR value.';
%Str = Str(1:1);
bits = dec2bin(Str, 7)';
bits = bits(:);
stego = cover;
stego(1:numel(bits)) = bitset(stego(1:numel(bits)), 1, str2num(bits)');
psnr(cover, stego)
Doing so will give you a PSNR of 73.9530 dB for the long string and 95.3265 dB for the 1-letter string.