Mittwoch, 28. Oktober 2015

Fast Fourier Transform on 2 Dimensional matrix using MATLAB



Fast Fourier transformation on a 2D matrix can be performed using the MATLAB built in function ‘fft2()’.

Fourier transform is one of the various mathematical transformations known which is used to transform signals from time domain to frequency domain.
The main advantage of this transformation is it makes life easier for many problems when we deal a signal in frequency domain rather than time domain.

Example:
%FOURIER TRANSFORM ON A MATRIX
A  = zeros(5);
A ( : ) = 1:25;
display(A);
F_FFT  = fft2(A);
display(F_FFT);
%INVERSE FOURIER TRANSFORM

I_FFT = ifft2(F_FFT);
display(abs(I_FFT));

NOTE on ABSOLUTE VALUE:
When we use FFT2() or FFT(),the result we obtain in the frequency domain is of complex data type.
i.e It contains both the real  as well as the imaginary part.
Let   A=10+5i
A is a complex number as it contains both real and imaginary part.In this particular case ‘10’ is the real part and ‘5’ is the imaginary part.
abs(A) = 11.1803 is the absolute (also called modulus in few books or notations) value of A which is nothing but the magnitude. It can be arrived by using the below mentioned formula:
abs(A) = sqrt(real part^2+imaginary part^2).
              = sqrt(10^2+5^2)
              = sqrt(125)
             = 11.1803 (approx)
Let’s try to understand how the Fourier transform on 2 dimensional data works with a simple example.
This method will be helpful to understand the up samplingand down sampling in both spatial and frequency domain.


1.       Consider a matrix A

2.       Perform 1 D Fast Fourier transform(FFT) on each row

1D FFT on first row (Note that the absolute value is only displayed and not the actual imaginary number):


Similarly, perform  1D FFT on each row:


NOTE: The figure represents the 1 D FFT on each row and the result is the absolute value of the complex data obtained using FFT.
3.       Perform 1 D Fast Fourier transform on each column.
On the matrix obtained from the previous step, compute 1D FFT column wise.


4.       Display the results obtained.


Flow Chart for Fast Fourier Transform on 2D :

INVERSE FOURIER TRANSFORM:

1.       Perform Inverse Fourier Transform on each column

2.       Perform IFFT on each row

3.       Display the original data


MATLAB CODE:
A=[110 20 140 0 220;
   60 34 23 198 20;
   15 12 126 230 15;
   140 28 10 28 10;
   11 12 19 85 100];

FFT_row = zeros(size(A));
FFT_col = zeros(size(A));

%Perform FFT on each row
for i=1:size(A,1)
FFT_row(i,:) = fft(A(i,:));
end

display(FFT_row);
%display(abs(FFT_row));

%Perform FFT on each column

for i=1:size(A,2)
FFT_col(:,i) = fft(FFT_row(:,i));
end

display(FFT_col);
%display(abs(FFT_col));

%INVERSE FOURIER TRANSFORM

IFFT_row = zeros(size(A));
IFFT_col = zeros(size(A));

%Perform Inverse Fourier Transform on each column
for i=1:size(A,2)
IFFT_col(:,i) = ifft(FFT_col(:,i));
end



%Perform IFFT on each row

for i=1:size(A,2)
IFFT_row(:,i) = ifft(IFFT_col(:,i));
end


display(abs(A))





ALTERNATE METHOD FOR INVERSE FOURIER TRANSFORM:
Instead of using ifft2() or ifft(), we can also use the following method to obtain the original data from the Fast Fourier transformed result :
1.       Obtain the conjugate of the Forward FFT
2.       Perform Forward fast Fourier transform
3.       Obtain the conjugate of the result from step 2.
4.       Divide it by the number of elements present in the matrix
5.       Obtain the original matrix


MATLAB CODE:
Conj_F = conj(F_FFT);
Conj_FFT = fft2(Conj_F);
IFFT_conj = conj(Conj_FFT)/numel(Conj_FFT)
display(abs(IFFT_conj));



Reference: Digital Image Processing  by Rafael C.Gonzalez, fourth Chapter.


Montag, 19. Oktober 2015

Using Gmail Offline

GMail introduced a new feature recently, that is browsing mails offline.

Today we are going to see how to do that.

First you need to install Google Gears, you can download the online installer from here
http://gears.google.com/

Run the online installer and it will install Google Gears on your system.

Now open your GMail and navigate to the settings and then to the Labs tab, there you will find a feature called offline, Enable that.

Thats it you are almost done, just a few clicks away. It will ask your permission to install offline access for GMail, click next.Then you get a Google Gears security warning, allow it.Click ok in the next window and you are done.It will download all your mails to your hard drive for offline browsing. You can see the status in the status window.

Have fun browsing gamil offline.

Mittwoch, 14. Oktober 2015

Bit Plane Compression

                               This tutorial  explains in brief the compression of an image using bit plane slicing technique. This is a lossy compression technique. In other words,  part of the data is lost in the compression process compared to the original image.

Check out the post on bit plane slicing to understand better.

Let’s explain with a simple example how encoding and decoding is carried out in Bit plane compression. In this example, the Most Significant Bit(MSB) alone is considered and encoded. For better quality image retrieval, combination of various bit planes such as [8 7] ,[[8 7 6], [8 7 6 5] ..etc can be encoded and decoded. The numbers 8,7,6 , 5 ,..etc represent bit positions.

Compression:


Step 1: Consider a matrix A of size 3 x 5

Step 2: Obtain the binary equivalent of the values in the matrix A. TheMATLAB function ‘dec2bin’ can be used for conversion

Step 3: Extract the Most Significant Bit(MSB)  for each value in the matrix from the binary representation. The MATLAB function ‘bitget’ can be used for the same.

Step 4:Rearrange the above MSB values such that each row  contains 8 columns or 8 bits.

In the above example, we  have 3x5=15 values but we need 8 columns in each row.  It can be achieved by padding the matrix with zeros in the end in order to form a matrix which has 8 columns in each row.



Step 5: Convert the binary representation in each row to a decimal number and store it.
Use ‘bin2dec’ MATLAB function to convert binary values to decimal values.
In our example, decimal equivalent of [1 0 0 0 1 0 0 0] = 136 and [1 0 1 0 1 0 1 0] = 170



MATLAB CODE:

clear all
clc

A = [180 4 80 33 201; 120 27 11 160 28; 224 1 133 67 144];
A = uint8(A);

%Encoding

%Check whether zeros has to be appended to the matrix
rem = mod(numel(A),8);
if rem~=0
rem = 8-rem;
end

%Extract the MSB
bit8 = bitget(A,8);
b8 = bit8';
b8 = b8(:);
b8 = [b8;zeros(rem,1)];

%Reshape the matrix as such each row contains 8 columns
mat8 = reshape(b8,8,[])';
str8 = num2str(mat8);
str8 = str8(:,1:3:end);

%Convert the binary to decimal
compressedbit8 = uint8(bin2dec(str8));


Verify the compressed data and original data size for comparison of size used for storage.

MATLAB CODE:

whos A compressedbit8

Decompression:

For Decoding an image/matrix, the compressed / encoded data has to be provided as the input along with size of the original image/matrix and  the vector containing the position of the bits used for encoding in order.

Step 1: Convert the decimal value of the compressed data into binary format.


Step 2: Remove the extra zeros appended to the matrix, if needed.
Step 3: Reshape the matrix to size of the original matrix A using the MATLAB function ‘reshape’.

Step 4: Preallocate a matrix of same size of original matrix A and replace the MSB(Most Significant Bit) of each value in the matrix with the bit we decompressed in the previous step.
Use the MATLAB function ‘bitset’

Step 5: Display the final data.


MATLAB CODE:

%Decoding

%Convert Decimal to Binary
decompressedbit8 = dec2bin(compressedbit8,8);

%Reshape the matrix to the size of original matrix size
%And remove extra zeros appended to the matrix
dbit8 = decompressedbit8';
dbit8 = dbit8(:);
dbit8 = dbit8(1:end-rem);
dbit8 = reshape(dbit8,size(A,2),size(A,1))';

%Preallocate a matrix
Image = zeros([size(A,1) size(A,2)]);
slice8 = zeros([size(A,1) size(A,2)]);

%Set the MSB with the binary values obtained from decompressed matrix
ind_bit8 = find(dbit8=='1');
slice8(ind_bit8) = 1;
Image = bitset(Image,8,slice8);
Image = uint8(Image);

%Display data
display(Image);


 




The above method can be extended for images by extracting combination of bits.
Example: The 7 and the 8 th bit can be extracted and stored or 2,4,6 and 8 bit can also be extracted.

COMPRESSION:

MATLAB CODE:

%ENCODING
clear all
clc


%INPUT IMAGE
A = imread('cameraman.tif');

%Encoding
bitnums = [6;7;8]; %BIT PLANES

%CHECK IF PADDING WITH ZEROS IS NEEDED OR NOT
rem = mod(numel(A),8);
if(rem~=0)
rem = 8-rem;
end

%EXTRACT EACH BIT AND STORE IT IN THE MATRIX

forinc =1:length(bitnums)

Ind = bitnums(inc);

%EXTRACT THE 'n'th BIT
bitval = bitget(A,Ind);

%PAD WITH ZEROS AND RESHAPE THE MATRIX
bval = bitval';
bval = bval(:);
bval = [bval;zeros(rem,1)];

matv = reshape(bval,8,[])';
strv = num2str(matv);
strv = strv(:,1:3:end);

%CONVERT BINARY TO DECIMAL
compressedbitv(:,inc) = uint8(bin2dec(strv));

end

%STORE THE COMPRESSED DATA IN A FILE
%OPTIONAL
fp = fopen('compressed_data678.data','wb');
fwrite(fp,compressedbitv','uint8');
fclose(fp);


EXPLANATION:

In the given example, 6,7 and 8 bit planes are extracted and compressed.

The compressed data can be stored in a file, if needed.


Original Image size       = 64 KB
Compressed Image size = 24 KB 


NOTE: bitnums = [6;7;8]; Modify this line to compress combination of bits.
Some examples: bitnums=[8] or bitnums=[2;4;6;8] or bitnums=[5;6;7;8]

DECOMPRESSION:

%DECOMPRESSION
clear all
clc

%INPUT FROM THE USER
M = 256; %SIZE OF THE ORIGINAL IMAGE
N = 256; %SIZE OF THE ORIGINAL IMAGE
bitnums = [6;7;8]; %BIT PLANES USED

rem = mod(M*N,8);

if(rem~=0)
rem = 8-rem;
end

%READ THE COMPRESSED DATA
fp = fopen('compressed_data678.data','rb');
compressedbitv = fread(fp,[length(bitnums),Inf],'uint8')';
fclose(fp);

%PREALLOCATE THE MATRIX
Image = zeros([M N]);
forinc = 1:length(bitnums)

Ind = bitnums(inc);

%CONVERT DECIMAL TO BINARY
decompressedbitv = dec2bin(compressedbitv(:,inc),8);

%REMOVE EXTRA ZEROS AND RESHAPE THE MATRIX
dbitv = decompressedbitv';
dbitv = dbitv(:);
dbitv = dbitv(1:end-rem);
dbitv = reshape(dbitv,N,M)';

%SET THE 'n'th BIT
slicev = zeros([M N]);
ind_bitv = find(dbitv == '1');
slicev(ind_bitv) = 1;
     Image = bitset(Image,Ind,slicev);

end

%DISPLAY THE IMAGE
Image = uint8(Image);
figure,imagesc(Image);colormap(gray);

Bit Plane 8

Bit Planes 7,8

Bit Planes 2,4,6 and 8

EXPLANATION:

The bit planes 6, 7 and 8 are extracted and the image is formed using those bits.

NOTE:
For decoding the following lines should be modified during each run.
%INPUT FROM THE USER
M = 256; %SIZE OF THE ORIGINAL IMAGE
N = 256; %SIZE OF THE ORIGINAL IMAGE
bitnums = [6;7;8]; %BIT PLANES USED

The size of the original image should be given as an input. Update M and N with the number of rows and columns of the original image.
The vector ‘bitnums’ should be exactly same as the one in the encoding procedure.
Whenever, ‘bitnums’ is modified during encoding then it should be modified during decoding process as well.

Donnerstag, 8. Oktober 2015

Partially Colored gray scale Images

                                  

                                          A RGB image contains three components. Namely: Red, Blue and Green.

The below figure represents various colors and their corresponding RGB (Red , Green and Blue) component values.


Gray scale value of the above RGB components:

A gray scale image can be formed from a RGB image by taking the sum of 29.89% of pixel value of Red component, 58.70% of pixel value of green component and 11.40% of pixel value of Blue component.




For instance, consider the second shade with values [150 9 22] from the color vector.
The corresponding gray scale value = (150*0.2989)+(9*.5870)+(22*.1140)
                                                                = 52.62
                                                                = 53 (approximately) 



Consider the gray scale values 61 ,106 and 83 from the gray scale vector.
If the gray scale value is updated in the RGB components of the colored vector then that particular shade will be in gray scale as shown below.
The value 61 is updated in Red, Green and Blue components. Similarly, 106 and 83 are also updated.


Using this principle, we can use both RGB and gray color in a single image to obtain a partially colored gray scale image.



Let us now learn how to obtain partially colored gray scale image.

Step 1: Read the input RGB image and its corresponding RGB components
 1.       Read an RGB Image
 2.       Store the Red component in matrix R, Green in matrix G and Blue in matrix B.
Step 2:  Define the Grayscale Image
1.       Convert RGB Image to Grayscale Image (GS)
2.       Create a matrix R1, G1 and B1 of the same size of matrix R, G and B
3.       Update the matrices R1,G1 and B1 with the value of the matrix GS

Step 3: Create a Mask
1.       Create a matrix of size GS
2.       Update the pixel positions with one if the pixel position should be RGB else zero or vice versa.
Step 4:  Find the index of the masked positions from the Mask
Step 5:  Create partial color and gray scale
1.       Obtain the Red component (R) for the corresponding index of the mask and update it in the R1 matrix. Similarly, update the other matrices G1 and B1 with values of G and B matrices based on the index of the mask.
2.       Create a Three dimensional matrix of the same size of RGB Image
3.       Update the three dimensional matrix with the R1, G1 and B1 components. This is the required partially coloured gray scale image.
Step 6:  Display the partially colored gray scale image




MATLAB CODE:

%Read a RGB image
A = imread('watch1.jpg');
R = A(:,:,1); %RED component
G = A(:,:,2); %GREEN component
B = A(:,:,3); %BLUE component



%RGB to Gray scale Image
GS = rgb2gray(A);
R1 = GS;
G1 = GS;
B1 = GS;

%Mask - Circle

wndow = uint8((gausswin(size(A,1),12)*gausswin(size(A,2),7)')*255);
wndow = ~wndow;








%Find Index
X = find(wndow==0);

R1(X) = R(X);
G1(X) = G(X);
B1(X) = B(X);

%Create a RGB matrix
C = zeros(size(A));
C(:,:,1) = R1;
C(:,:,2) = G1;
C(:,:,3) = B1;

C = uint8(C);

figure,imshow(C);




 The mask can also be created manually as shown below: