LSB watermarking using MATLAB
Lately at university, I have been following the “Data Hiding” course. Basically the lecture are focused on digital watermarking (on images and audio files), and cryptography.
One of the first lab lessons was about LSB (least significant bit) replacement. The idea behind this watermarking technique is the following: if you see you image as a matrix NxM (where N and M are the dimension of the image) you can represent the value of the pixel in the position (i,j) as a binary number; this binary can be then divided in all of its bit, so that you will have a most significant bit (the one that contains quite a lot of information, and a least significant bit that contains few information).
If your image is for example in gray scale, you can make changes to the value of the LSB without any perceptible distortion for the human user therefore you can think of taking the LSB of an image (the cover image) and change its value in every pixel with the MSB of another image, that we would like to embed in a secret/non perceptible way in the cover image). For my code I used two bitmap image, unfortunately wordpress doesn’t allow me to publish bmp images, so I’m just going to put here the links for getting the images from the web: http://www.ece.rice.edu/~wakin/images/lena512.bmp http://www.eecs.qmul.ac.uk/~phao/CIP/Images/Baboon.bmp
Ok, now (as always) a lot of code about LSB watermarking and few words about it 😀 Briefly with the following code I will try to embed the MSB of the baboon image into the picture of Lena by exploiting the LSB embedding technique. We will try also to add an WGN (white gaussian noise) to the image then after these operations we will write to file the results. The code is heavily commented, so I think that further explanations are not needed.
%Project: Tutorial on Least Significant Bit Substitution % Watermark Embedding clear all; % read in the cover object you want to use for embedding file_name='lena.bmp'; cover_object=imread(file_name); % read the message image you want to hide in the cover image file_name='baboon.bmp'; message=imread(file_name); % conversions needed to spread the image values on a 256 gray-scale message=double(message); message=round(message./256); message=uint8(message); % determine the size of cover image used for embedding Mc=size(cover_object,1); %Height Nc=size(cover_object,2); %Width % determine the size of message object to embed Mm=size(message,1); %Height Nm=size(message,2); %Width %y = uint8(wgn(Mm,Nm,1)); % title the message object out to cover object size to generate watermark for ii = 1:Mc for jj = 1:Nc watermark(ii,jj)=message(mod(ii,Mm)+1,mod(jj,Nm)+1); end end % set the LSB of cover_object(ii,jj) to the value of the MSB of watermark(ii,jj) watermarked_image=cover_object; for ii = 1:Mc for jj = 1:Nc watermarked_image(ii,jj)=bitset(watermarked_image(ii,jj),1,watermark(ii,jj)); end end % add noise to watermarked image noisy = imnoise(watermarked_image,'gaussian'); % write to file the two images imwrite(watermarked_image,'lsb_watermarked.bmp','bmp'); imwrite(noisy,'lsb_watermarked_noise.bmp','bmp'); % display watermarked image figure(1) imshow(watermarked_image,) title('Watermarked Image') % display watermarked and noised image figure(2) imshow(noisy,) title('Watermarked and noised Image')
So if you execute this code you are going to have on screen and on disk two images, that I can’t dsiplay here because they are bmp files.
Now let’s see how to recover the watermark:
%Project: Tutorial on Least Significant Bit Substitution % Watermark Recover clear all; % read in watermarked image file_name='lsb_watermarked.bmp'; watermarked_image=imread(file_name); % determine size of watermarked image Mw=size(watermarked_image,1); %Height Nw=size(watermarked_image,2); %Width % use lsb of watermarked image to recover watermark for ii = 1:Mw for jj = 1:Nw watermark(ii,jj)=bitget(watermarked_image(ii,jj),1); end end % scale the recovered watermark watermark=256*double(watermark); % scale and display recovered watermark figure(1) imshow(watermark,) title('Recovered Watermark')
Try the code and let me know in case of troubles!