Wednesday, June 25, 2008

A4 - Enhancement by Histogram Manipulation

HISTOGRAM MANIPULATION: LINEAR CDF

This activity is designed to improve the quality of an image by manipulating its histogram. Histogram manipulation enhances certain image features such as brightness and contrast. The image below is a good example for histogram manipulation since as shown, the image seems to be too dark.


*http://www.dphclub.com/tutorials/images/war-time-1.jpg

The observation that the image is dark is supported by plotting its histogram. The histogram of a grayscale image is equal to the graylevel probability distribution function (PDF) if normalized by the total number of pixels. (AP186 Notes, Maricor Soriano, 2008) Observe that pixel values of the image cluster on the darker region of the PDF, that is near the lower values of the gray level. The lowest pixel value of the image is equal to 15 while the highest is 114.



We then get the Cumulative Distribution Function (CDF) of the image from its PDF, simply by getting the cumulative sum of the values in the PDF.



The CDF is nonlinear and the values cluster on the darker region of the CDF. We then use this CDF to map each pixel of the original image to a new array with the CDF as the mapping function. The resulting image is shown below.



As observed, the image is much brighter than the original. This is because, after mapping the original image using its CDF, the pixel values of the image is 'stretched' within the 0-255 gray levels, therefore values where evenly distrbuted within the gray level The histogram plot below signifies that a slightly even distribution actually happened.


Since the values were evenly distributed (relatively) among the gray levels, the expected CDF must be linear. The 'ringings' on the lower part is caused by contributions from the darker gray levels which are relatively more than those present in the lighter side. (see histogram) This is again due to the fact that the original image has more darker values than lighter ones.

Here is the code I used:
---

getf('imhist.sci');

im=imread('image_tc.jpg'); //opens a 24 bit image
im=im(:,:,1);
imwrite(im(:,:), 'image_gs.jpg'); //converts to 8 bit grayscale image
im=imread('image_gs.jpg'); //saves the grayscale image
[val,num]=imhist(im);
imsize=size(im,1)*size(im,2);
normCDF=cumsum(num/imsize);
h=scf(1); plot(val, num/imsize);
h=scf(2); plot(val,normCDF);

//pixel mapping using CDF of image
imnew=[];
for i=1:size(im,1)
for j=1:size(im,2)
imnew(i,j)=normCDF(find(im(i,j)==val));
end
end

imwrite(imnew,'image_enhanced.jpg'); // saves enhanced image after mapping
imenhanced=imread('image_enhanced.jpg');
[val,num]=imhist(imenhanced);
imsize=size(imenhanced,1)*size(imenhanced,2);
normCDF=cumsum(num/imsize);
h=scf(3); plot(val, num/imsize);
h=scf(4); plot(val,normCDF);
---
***imhist.sci is the histogram plotting code written by Jeric Tugaff


HISTOGRAM MANIPULATION: NON-LINEAR CDF

Below is a flowchart of pixel backprojection using a non-linear CDF, as summarized by Dr. Maricor Soriano in her lecture notes.



The following is an enhanced image after mapping the original pixel values using a nonlinear CDF given by the equation G=1/2+ 1/2(tanh(16*((z-128)/255))) where z is from 0-255.



The histogram of this enhanced image is shown below with its CDF as well. The blue plot is the CDF used for mapping while the red plot is the CDF of the enhanced image. The difference in the CDF is probably due to the interpolation method I used in pixel backprojection. (click CDF plot for a clearer view)


I observed that the sigmoid CDF I used didn't enhance the image well as seen with the naked eye. I experimented with using a parabolic function as my desired CDF.

G=(z.^2);
G=G/max(G);

where z is again between 0-255. I divided it with its maximum value to obtain a function with 1 as the highest value. The enhanced image is shown below.



Below is the histogram and CDF of this image. The blue plot is the desired CDF, red plot is the CDF of the enhanced image. (click CDF plot for a clearer view) The difference in the CDF is probably due to the interpolation method I used in pixel backprojection.


Here is the code I used:
---

getf('imhist.sci');

im=imread('image_tc.jpg'); //opens a 24 bit image
im=im(:,:,1);
imwrite(im(:,:), 'image_gs.jpg'); //converts to 8 bit grayscale image
im=imread('image_gs.jpg');
[val,num]=imhist(im);
imsize=size(im,1)*size(im,2);
normCDF=cumsum(num/imsize);
h=scf(1); plot(val, num/imsize);
h=scf(2); plot(val,normCDF);

z=[0:255];
G=(1+(tanh(16*((z-128)/255))))/2;
//G=(z.^2);
//G=G/max(G);
h=scf(5); plot(z,G,'b');

imnew=[];
imnew2=[];
for i=1:size(im,1)
for j=1:size(im,2)
imnew(i,j)=normCDF(find(im(i,j)==val));
end
end

imnew2=interp1(G,z,imnew);
imnew2=round(imnew2);
h=scf(3); imshow(imnew2,[0 255]);

[val,num]=imhist(imnew2);
imsize=size(imnew2,1)*size(imnew2,2);
normCDF=cumsum(num/imsize);
h=scf(4); plot(val, num/imsize);
h=scf(5); plot(val,normCDF,'r');
---
***imhist.sci is the histogram plotting code written by Jeric Tugaff

--o0o--

Collaborator: Jeric Tugaff
...thank you for the histogram plotting code and for the interp1 syntax

--o0o--
Grade: 10/10 since image was enhanced thru histogram manipulation and that CDF of enhanced image is almost the same as that of the desired CDF, especially for the nonlinear part.

No comments: