Lets Learn together... Happy Reading

" Two roads diverged in a wood, and I,
I took the one less traveled by,
And that has made all the difference "-Robert Frost

K means clustering on RGB image

                        I assume the readers of this post have enough knowledge on K means clustering method and it’s not going to take much of your time to revisit it again.


Let’s start with a simple example, consider a RGB image as shown below.


Let’s choose the number of clusters = 2. Basically we are going to separate the background (first cluster) and the flower (second cluster).

In the second step, let’s choose two random RGB pixel values.

Since the initial pixel values are completely random, we can clearly see that both the initial cluster points are on the flower and not on the background.
The pixel value of the cluster 1 (R1,G1,B1)=[255,191,59]
The pixel value of the cluster 2 (R2,G2,B2) = [255,245,11]

In the third step, find the Euclidean distance between the initial points and all the pixels in the image matrix.
We will see how to calculate the Euclidean distance between the initial points and the pixel value at (1,1) . The pixel value at (1,1) is [24,64,186]





Repeat the above procedure for all the pixel values.

The next step is finding the minimum value among the two clusters and fetch their corresponding cluster index. With reference to the pixel position at (1,1), the minimum value is 292.6072 and it belongs to the cluster 1. So update the matrix ‘ClusterMap’ with 1 at the position (1,1).
Similarly, find the index of the minimum value and update the ‘ClusterMap’ matrix for all the pixel positions.



The visual analysis of the first iteration shows that the clustering is not good and it still needs to be improved.
It’s time to look for new cluster points. Let’s see how to find new cluster points to perform better segmentation.
In order to obtain the new cluster points, compute the mean of the pixel values with respect to each cluster. Once we obtain the mean value for the Red, Green and Blue channels separately, find the difference between the new values and the current values.
In our chosen example,
The new values for the Red, Green and Blue channels are (R1_new,G1_new,B1_new)=[ 93.2942  106.6650  143.5914] for the first cluster
And (R2_new,G2_new,B2_new)=[ 252.1034  224.2628    3.8519] for the second cluster

The difference between the new and the current values with respect to different color channels are
[  161.7058   84.3350   84.5914] for first cluster (R1-R1_new,G1-G1_new,B1-B1_new)
 [  2.8966   20.7372    7.1481] for the second cluster (R2-R2_new,G2-G2_new,B2-B2_new)




If the difference is more than the threshold value then assign the new values to the current values and continue from the third step i.e calculating the Euclidean distance else stop the process and display the clustered image.

In our example, after the fifth iteration the difference between the new and the current values of the
  1st cluster [0.1615    0.1734    0.5675] and 2nd cluster [0.4701    0.5028    0.0364]  indicates that the values are less than 1 for each color channel individually.
The final segmented images are shown below.
%K means clustering
%Author: Aaron Angel

clear all
close all
clc
%READ A RGB IMAGE
A = imread('flower8.jpg');
figure,subplot(121),imagesc(A);title('RGB Image');hold on;

A = double(A);

%CARTESIAN GRID FOR THE 2D IMAGE
[Xp,Yp] = meshgrid(1:size(A,2),1:size(A,1));

%NUMBER OF CLUSTERS
num_clusters = 4;

%THRESHOLD VALUE FOR EACH CHANNEL
Tval = 1;

%GLOBAL THRESHOLD VALUE
Global_Tval = 3;

%RANDOM IMAGE POSITIONS
RX = randi(size(A,1),1,num_clusters);
RY = randi(size(A,2),1,num_clusters);



%PREALLOCATE THE VECTORS
RGB_val = zeros([num_clusters,3]);
RGB_new = zeros([num_clusters,3]);

%FETCH THE RGB PIXEL VALUE OF THE RANDOM IMAGE POSITIONS
for j = 1:num_clusters
   RGB_val(j,:) = A(RX(j),RY(j),:); 
end


myvox = zeros([size(A,1) size(A,2) num_clusters]);
flag = 1;

Rcomp = A(:,:,1); %RED CHANNEL
Gcomp = A(:,:,2); %GREEN CHANNEL
Bcomp = A(:,:,3); %BLUE CHANNEL
it=0;


while flag==1
 
 %EUCLIDEAN DISTANCE BETWEEN THE RANDOM RGB PIXEL VALUE
 %AND THE PIXEL VALUES IN THE IMAGE
 for j = 1: num_clusters
     myvox(:,:,j) = sqrt((A(:,:,1)-RGB_val(j,1)).^2+(A(:,:,2)-RGB_val(j,2)).^2+(A(:,:,3)-RGB_val(j,3)).^2);
 end

%FIND THE MINIMUM VALUE(Y) AND THE CORRESPONDING CLUSTER NUMBERS(ClusterMap)
[Y,ClusterMap] = min(myvox,[],3);


%MEAN VALUE PIXEL VALUES IN EACH CHANNEL WITH RESPECT TO THE CLUSTERS
for j = 1:num_clusters
  
   RGB_new(j,1) = mean(Rcomp(ClusterMap(:)==j));
   RGB_new(j,2) = mean(Gcomp(ClusterMap(:)==j));
   RGB_new(j,3) = mean(Bcomp(ClusterMap(:)==j));
end

%DIFFERENCE BETWEEN THE NEW VALUE AND THE OLD VALUE
DiffVal = abs(RGB_val-RGB_new);


%IF THE DIFFERENCE IS LESS,STOP THE ITERATION ELSE
%ASSIGN THE NEW VALUE AND CONTINUE
if(sum(DiffVal(:)) < Global_Tval)
    flag = 0;
else
  if(sum(DiffVal(:,1))>Tval)
    RGB_val(:,1) = RGB_new(:,1);
  end
  if(sum(DiffVal(:,2))>Tval)
    RGB_val(:,2) = RGB_new(:,2);
  end
  if(sum(DiffVal(:,3))>Tval)
     RGB_val(:,3) = RGB_new(:,3);
  end
end




%NUMBER OF ITERATIONS
it=it+1

end;
subplot(122),imagesc(ClusterMap);title('Clusters');colormap(jet);


%DISPLAY THE SEGMENTED IMAGE BASED ON COLORS
m=2;
n = round(num_clusters/m);
for k=1:num_clusters
F = repmat(logical(ClusterMap==k),1,1,3).*double(A);
figure(2),subplot(n,m,k),imagesc(uint8(F));hold on;
end



EXPLANATION:


In this example, the number of clusters are 4, so the yellow, pink and blue flowers are defined as clusters separately while the remaining details are combined as one cluster.



Hope you all enjoyed the post. Feel free to comment and join us in Facebook and twitter for more updates.
like button Like "IMAGE PROCESSING" page

Hide Image inside an Image

The tutorial on hiding the text messages inside the image should have given enough knowledge on bit replacing method. Also check Bit plane slicing to learn more about bit planes.
In this tutorial, we will start in the reverse order i.e. Let’s first perform decryption and then we will learn about encryption.


Download the encrypted image and run this decryption code below to see the hidden image inside the cover image.



Encrypt_Image1.png







MATLAB CODE:

%DECRYPT IMAGE
clear all

%READ THE ENCRYPTED IMAGE
A = imread('Encrypt_Image1.png');

%RED,GREEN AND BLUE COMPONENTS
Red_ch = A(:,:,1);
Green_ch = A(:,:,2);
Blue_ch = A(:,:,3);

%INTERVAL
Dt = bitget(Red_ch(1:8),1);
Dt = double(bi2de(Dt));

%NUMBER OF COLUMNS
Ncols = bitget(Red_ch(9:16),1);
Ncols = double(bi2de(Ncols));

%NUMBER OF ROWS
Nrows = bitget(Red_ch(17:24),1);
Nrows = double(bi2de(Nrows));

%FETCH THE LEAST SIGNIFICANT BIT FROM THE ENCRYPTED IMAGE
EndPoint = (Dt*Nrows*Ncols*8)+24;
Decrypt_Red = bitget(Red_ch(25:Dt:EndPoint),1);
Decrypt_Green = bitget(Green_ch(25:Dt:EndPoint),1);
Decrypt_Blue = bitget(Blue_ch(25:Dt:EndPoint),1);

Decrypt_Red = reshape(Decrypt_Red,8,[])';
Decrypt_Red = bi2de(Decrypt_Red);
Decrypt_Red = reshape(Decrypt_Red,Ncols,Nrows);

Decrypt_Green = reshape(Decrypt_Green,8,[])';
Decrypt_Green = bi2de(Decrypt_Green);
Decrypt_Green = reshape(Decrypt_Green,Ncols,Nrows);

Decrypt_Blue = reshape(Decrypt_Blue,8,[])';
Decrypt_Blue = bi2de(Decrypt_Blue);
Decrypt_Blue = reshape(Decrypt_Blue,Ncols,Nrows);

Decrypted_Image = zeros([Ncols,Nrows,3]);
Decrypted_Image(:,:,1)=Decrypt_Red;
Decrypted_Image(:,:,2)=Decrypt_Green;
Decrypted_Image(:,:,3)=Decrypt_Blue;

Decrypted_Image = uint8(Decrypted_Image);


figure,imshow(Decrypted_Image);title('Secret Image');



ENCRYPTION:

MATLAB CODE:

%ENCRYPTION
clear all

%READ THE COVER IMAGE
I = imread('peppers.png');

%READ THE IMAGE TO HIDE
J = imread('cube.jpg');

%PREALLOCATE THE OUTPUT IMAGE
Output = zeros(size(I));
%REPRESENT THE NUMBER OF ROWS AND COLUMNS OF THE SECRET IMAGE
%IN BINARY FORMAT
Jsize = de2bi([size(J,1),size(J,2)]);

%RED,GREEN AND BLUE COMPONENTS OF THE SECRET IMAGE
Red_Ch = J(:,:,1);
Green_Ch = J(:,:,2);
Blue_Ch = J(:,:,3);

%CONVERT THE RED COMPONENT OF THE SECRET IMAGE INTO BINARY FORMAT
Encrypt_Red = de2bi(Red_Ch(:),8)';
Encrypt_Red = Encrypt_Red(:)';

%CONVERT THE GREEN COMPONENT OF THE SECRET IMAGE INTO BINARY FORMAT
Encrypt_Green = de2bi(Green_Ch(:),8)';
Encrypt_Green = Encrypt_Green(:)';

%CONVERT THE BLUE COMPONENT OF THE SECRET IMAGE INTO BINARY FORMAT
Encrypt_Blue = de2bi(Blue_Ch(:),8)';
Encrypt_Blue = Encrypt_Blue(:)';

%CALCULATE THE INTERVAL AND CONVERT IT INTO BINARY FORMAT
dt=floor((size(I,1)*size(I,2))/numel(Encrypt_Red));
Bi_dt = de2bi(dt,8);

Info_data = [Bi_dt,Jsize(1,:),Jsize(2,:)];

%RED,GREEN AND BLUE COMPONENT OF THE COVER IMAGE
Red_mat = I(:,:,1);
Green_mat = I(:,:,2);
Blue_mat = I(:,:,3);

% INTERVAL,NUMBER OF COLUMNS, NUMBER OF ROWS
Red_mat(1:24) = bitset(Red_mat(1:24),1,Info_data);
Green_mat(1:24) = bitset(Green_mat(1:24),1,Info_data);
Blue_mat(1:24) = bitset(Blue_mat(1:24),1,Info_data);

%%REPLACE THE LEAST SIGNIFICANT BIT OF THE COVER IMAGE
%WITH THE BINARY FORMAT OF THE SECRET IMAGE
EndValue = numel(Encrypt_Red)*dt+24;
Red_mat(25:dt:EndValue) = bitset(Red_mat(25:dt:EndValue),1,Encrypt_Red);
Green_mat(25:dt:EndValue) = bitset(Green_mat(25:dt:EndValue),1,Encrypt_Green);
Blue_mat(25:dt:EndValue) = bitset(Blue_mat(25:dt:EndValue),1,Encrypt_Blue);

%ENCRYPTED IMAGE
Output(:,:,1) = Red_mat;
Output(:,:,2) = Green_mat;
Output(:,:,3) = Blue_mat;
Output = uint8(Output);

figure,subplot(121),imshow(I); subplot(122),imshow(Output);
 
%DIFFERENCE BETWEEN THE ORIGINAL AND THE ENCRYPTED IMAGE
figure,imagesc(double(I)-double(Output));colormap(jet);colorbar;

%WRITE THE ENCRYPTED IMAGE IN THE PNG FORMAT
imwrite(Output,'Encrypt_Image1.png');




EXPLANATION:

Were you able to extract the encrypted image? The type of the cover image is RGB and the secret image is also RGB. The Red channel of the cover image is encrypted with the Red channel of the secret image, Green channel of cover image with the green channel of the secret image. Similarly the encryption is done on the blue channel.

NOTE: 
  • The size of the cover image after encryption should not be modified
  • Save the encrypted image with lossless compression method
  • Size of the secret image should be less than 10% of the cover image
like button Like "IMAGE PROCESSING" page
Previous Post Next Post Home
Google ping Hypersmash.com