Tuesday, June 30, 2009

Activity 4 - Enhancement by Histogram Manipulation

The program Adobe Photoshop is very well-known for easy handling of various images like adjusting the contrast, adding special effects, among many more. In this activity, we are rather to enhance an image through manipulating the histogram of the image's grayscale values using Scilab.

The first step of course is to find an image which has poor contrast. I have found this image from the web as shown below.


Source: http://www.american-indian-artwork.com/photograph-restoration-tutorial.htm

The image to be enhanced is strictly a grayscale type which possesses 0 to 255 grayscale values. The graylevel probability distribution function (PDF) of this image is what we manipulated using two main methods: first is through the backprojection using its original cumulative probability function (CDF) and the other is through backprojection via a desired CDF.

The PDF of my image under enhancement is illustrated below. The CDF is then acquired through the cumulative sum of the PDF. The PDF and CDF of the original image are shown as follows.



Based from its histogram, the image really has a poor contarst because the grayscale values are concentrated in the region near 0 or pure black.

In the backprojection of the grayscale values through the original CDF of the image, each pixel value is corresponded to its y-value in the original CDF and replaced by it. The effect of this first method is illustrated below.


The image is excellently enhanced in this method because it results to a more recognizable image where details are not sacrificed.

Then the PDF and CDF of this enhanced image are the following.



It can be observed from the enhanced CDF that it follows a staright line (y = x) thus distributing the pixel values from 0 to 255 linearly in the same form of the original CDF.

The second method which is the backprojection using a desired CDF is done initially by finding the original CDF value from the pixel grayscale. Then, this is traced in the value of the desired CDF. Finally, this pixel value is replaced by the pixel value at the desired CDF having the same CDF value. The same algorithm is applied to all the pixel values of the original CDF.

For a simple case, I used a parabolic function y = x^2 as a desired CDF. The effect of this CDF to the original image is shown below.


It can be observed that the contrast enhancement thorugh a parabolic CDF is somehow not applicable for this image since it is too bright.

The following are the PDF and CDF of this enhanced image via a parabolic CDF.



The PDF is similar to the first method except that in this parabolic CDF, the histogram is not well spreaded over the grayscale values. Apparently, the CDF follows the contour of a parabola which in turn make the image highly contrasted compared to the first method.

I have also tried when a placed a linear function (y = x). I anticipate that this will result to the first method. And I am correct. The first algorithm is exactly doing the second method but with a linear CDF.

Finally, using the same second method, I replaced the parabolic function into a nonlinear CDF which mimicks a nonlinear response like the human eye. Here, I have chosen a logarithmic one which is y = log(x).

The effect is as follows.


Some details of the image are lost in this kind of contrast enhacement which implies that the nonlinear CDF is not applicable for my image.

Meanwhile, its PDF and CDF are illustrated below.



The PDF for this nonlinear logarithmic CDF is not well-distributed. Due to this nonlinearity, the spacings along the grayscale values are not uniform and the probability values are not high. Like the parabolic CDF, the CDF of the enhanced image follows the graph of the desired CDF which is a logarithmic function here, and this makes the quality of the image not that good.

In summary, here are the original image and its enhanced images using the two methods (the second is composed of two kinds of functions).



The first one is the original image, the second is the enhanced image from its original CDF (linear backprojection), the third is used with a parabolic CDF, and finally with a logarithmic CDF. I can conclude that the first method or implementing a linear CDF is the best process for the contrast enhancement of my image.

I grade myself 10/10 in this activity since I am able to enhance a grayscale image through the manipulation of its PDF using two main procedures successfully.

The following are my collaborators in this activity: Gary, Ed, Raffy, Neil, and Earl.

Appendix
The whole code in Scilab utilized in this activity is as follows.

poor = imread('poor_contrast.jpg'); // For histogram (PDF) of the original image
imfinfo('poor_contrast.jpg');

a_poor = 1;
grayscale_poor = [];
pixels_poor = [];
for i = 0:255
[x_poor, y_poor] = find(poor == i);
grayscale_poor(a_poor) = i;
pixels_poor(a_poor) = length(x_poor);
a_poor = a_poor + 1;
end

scf(0);
imshow(poor/max(poor));

scf(1)
subplot(211)
plot(grayscale_poor, pixels_poor/max(pixels_poor));
title('PDF of Original Image');
xlabel('Grayscale Values');

cdf_0_poor = cumsum(pixels_poor); // For CDF of the original image
cdf_poor = cdf_0_poor/max(cdf_0_poor);
subplot(212)
plot(grayscale_poor, cdf_poor)
title('CDF of Original Image');
xlabel('Grayscale Values');

good1= []; // For backprojection of the image through the original CDF
for i = 1:size(poor,1)
for j = 1:size(poor,2)
good1(i,j) = cdf_poor(poor(i,j));
end
end

scf(2);
imshow(good1);

//imwrite(good1, 'good_contrast_linear.jpg');

good1 = round(good1*255); // For histogram (PDF) of the enhanced image through the original CDF
a_good1 = 1;
grayscale_good1 = [];
pixels_good1 = [];
for i = 0:255
[x_good1, y_good1] = find(good1 == i);
grayscale_good1(a_good1) = i;
pixels_good1(a_good1) = length(x_good1);
a_good1 = a_good1 + 1;
end

scf(3);
subplot(211);
plot(grayscale_good1, pixels_good1/max(pixels_good1));
title('PDF of Enhanced Image via Linear Function');
xlabel('Grayscale Values');

cdf_0_good1 = cumsum(pixels_good1); // For CDF of the enhanced image through the original CDF
cdf_good1 = cdf_0_good1/max(cdf_0_good1);
subplot(212);
plot(grayscale_good1, cdf_good1);
title('CDF of Enhanced Image via Linear Function');
xlabel('Grayscale Values');

// Image enhancement through a desired CDF

z = [0:255]; // CDF definition
parabola = z^2;
parabola = parabola/max(parabola);

good2 = []; // For backprojection through a desired CDF
for i = 1:size(poor, 1)
for j = 1:size(poor, 2)
dummy = abs(cdf_poor(poor(i, j)) - parabola);
dummy = find(dummy == min(dummy));
good2(i,j) = dummy;
end
end

good2 = good2/max(good2);
scf(4);
imshow(good2);

//imwrite(good2, 'good_parabola.jpg');

good2 = round(good2*255); // For histogram (PDF) of the enhanced image through a desired CDF
a_good2 = 1;
grayscale_good2 = [];
pixels_good2 = [];
for i = 0:255
[x_good2, y_good2] = find(good2 == i);
grayscale_good2(a_good2) = i;
pixels_good2(a_good2) = length(x_good2);
a_good2 = a_good2 + 1;
end

scf(5);
subplot(211);
plot(grayscale_good2, pixels_good2/max(pixels_good2));
title('PDF of Enhanced Image via Parabolic Function');
xlabel('Grayscale Values');

cdf_0_good2 = cumsum(pixels_good2); // For CDF of the enhanced image through a desired CDF
cdf_good2 = cdf_0_good2/max(cdf_0_good2);
subplot(212);
plot(grayscale_good2, cdf_good2);
title('CDF of Enhanced Image via Parabolic Function');
xlabel('Grayscale Values');

// Enhancement through a nonlinear function

v = [0:255]; // Nonlinear CDF definition
non = log(v + 1);
non = non/max(non);

good3 = []; // For backprojection of the image through a nonlinear CDF
for i = 1:size(poor, 1)
for j = 1:size(poor, 2)
dummy = abs(cdf_poor(poor(i, j)) - non);
dummy = find(dummy == min(dummy));
good3(i,j) = dummy;
end
end

good3 = good3/max(good3);
scf(6);
imshow(good3);

//imwrite(good3, 'good_nonlinear_log.jpg');

good3 = round(good3*255); // For histogram (PDF) of the enhanced image through a nonlinear CDF
a_good3 = 1;
grayscale_good3 = [];
pixels_good3 = [];
for i = 0:255
[x_good3, y_good3] = find(good3 == i);
grayscale_good3(a_good3) = i;
pixels_good3(a_good3) = length(x_good3);
a_good3 = a_good3 + 1;
end

scf(7);
subplot(211);
plot(grayscale_good3, pixels_good3/max(pixels_good3));
title('PDF of Enhanced Image via Nonlinear Function');
xlabel('Grayscale Values');

cdf_0_good3 = cumsum(pixels_good3); // For CDF of the image through a nonlinear CDF
cdf_good3 = cdf_0_good3/max(cdf_0_good3);
subplot(212);
plot(grayscale_good3, cdf_good3);
title('CDF of Enhanced Image via Nonlinear Function');
xlabel('Grayscale Values');

No comments:

Post a Comment