Monday, June 30, 2008

Enhancement by Histogram Manipulation

In this activity, we enhanced a poor contrast grayscale image by manipulating its histogram. To do this, I first get a histogram of the poor contrast image.










Image taken from http://www.onlinetelemedicine.com/html/product/sam_images/X-Ray.jpg

As we can see in this histogram, the pixel values do not occupy the whole grayscale range(0-255). Instead, it is limited only the middle values of the grayscale, specifically 3-175.
To enhance this image, I need to backproject the image using the CDF of its histogram. The CDF of the image is shown below.
The CDF is almost a straight line, but the range is only from 3-175. The backprojection was done as follows. For each pixel value, I would look up its corresponding y value in the CDF.

//SCILAB Code
imsize = size(image);

cy = cumsum(y);

cy = cy/max(cy); //normalized CDF y-value
for i = 1:imsize(1)
for j = 1:imsize(2)

index = find(x == image(i, j));
image(i,j) = cy(index);
end
end

//code end

After the backprojection, the image and its CDF are transformed as seen below.












The image after backprojection has a much better contrast and its CDF now looks like a straight line which extends from 0-255.

The next part of this activity was to use a nonlinear CDF to backproject the image. The main steps to do this was from x1(original value of the pixel), we find its corresponding y in its CDF (y1). y1 is then traced to the desired CDF (y2). And lastly, find the corresponding x value of y2 (x2).
The left image is the original image and the right image is a tanh function.

//Scilab Code
imsize = size(image);
cy = cumsum(y);

cy = cy/max(cy);

scf(1);

plot(x, cy)
x = 0:255;

G = tanh(16.*(x-128)./255);

G = (G - min(G))./2;

scf(2);
plot(x, G)

for i = 1:imsize(1)

for j = 1:imsize(2)
index = find(x == image(i, j));

y1 = cy(index);

index2 = find(G <= y1);
image(i, j) = x(index2(max(index2)));

end

end

//code end

After the backprojection, the image and its CDF becomes:












The new CDF follows the tanh function.

For this activity I grade myself 10 because I was able to perform the required task and I worked independently.

Wednesday, June 25, 2008

Image Types and Image Thresholding

In this activity, different types of images were examined. Using the imfinfo function in SIP toolbox, the differences in the these images were observed.

Binary

Format PNG
Width 200
Height 141
Depth 8
StorageType indexed
NumberOfColors 2
Resolution (0, 0) cm


Grayscale

Format PNG
Width 200
Height 141
Depth 8
StorageType indexed
NumberOfColors 256
Resolution (1.031D+09, 1.031D+09) cm


Truecolor

Format PNG
Width 200
Height 150
Depth 8
StorageType truecolor
NumberOfColors 0
ResolutionUnit (3.436D+08, 3.436D+08) cm


Indexed

Format PNG
Width 200
Height 150
Depth 8
StorageType indexed
NumberOfColors 256
ResolutionUnit (3.436D+08, 3.436D+08) cm

*Images were taken from: grow.ars-informatica.ca/images/grass_close-up.jpg & upload.wikimedia.org/wikipedia/commons/thumb/9/9f/Southport_Sunset.PNG/800px-Southport_Sunset.PNG

The next part of this activity is to measure an area of a flat object using images. The image used here was a scanned ID.(with rulers on the x and y axis)

Format BMP
Width 500
Height 306
Depth 8
StorageType indexed
NumberOfColors 256
Resolution (- 3.436D+08, - 3.436D+08) cm
(NOTE: the rulers in the image was cropped)


Using Scilab, the histogram of this grayscale image was obtained.


From this histogram, we can the that the region of interest(ROI) is mostly separated from the background. There are only a few pixels which are not close to the peaks. The threshold I used was the average of the 2 highest peaks (~230), because if I used the first highest peak(~205) as the threshold, there are still parts of the object which were not included. However, if the second highest peak was used ( ~255), some of the background was included in the object.


After thresholding, the ID image becomes similar to the image on the left. Since some part of the ID was quite similar in color as the background, some of the background was included(quite evident in the lower right region of the object). But these are only minimal and it was not expected that it would have a large difference in the final results.

The area of the thresholded image was calculated using Green's theorem. The obtained area was 101656.5 sq. pixels. Using the rulers in the image(and by pixel counting), the conversion from pixel to mm was found to be 46pixels = 10mm. So 4.6x4.6 pixels = 21.16 sq.pixels = 1 sq. mm. Using this conversion and the value obtained from Green's theorem, the area of the ID was computed to be (101656.5/21.16)*1sq.mm = 4804.18 sq. mm. To see if this calculation was correct, I measured the dimensions of the ID and calculated its area. The area using this was 54mm*86mm = 4644 sq. mm. The calculated area using images have a 3.4% error compared to the area calculated physically.

For this activity, I give myself a grade of 10 since I performed the activity quite well and without help from others.

Scilab code for histogram and threshold:
pict = imread("idimage.bmp");
if max(pict) <= 1 //indexed, colored image
x = 1:256;
pict = im2gray(pict) * 255 + 1;
pict = round(pict);
else //indexed, grayscale
x = 1:256;
end
y = x.*0;
mat = size(pict);
for i = 1:mat(1)
for j = 1:mat(2)
y(pict(i, j)) = y(pict(i, j)) + 1;
end
end
bar(x, y)
//end of histogram

//thresholding
srt = sort(y);
for i = 1:256
if y(i) == max(y);
max_x = i;
elseif y(i) == srt(2)
max_x2 = i;
end
end
ave = (max_x + max_x2)/2;
thresh = round(ave);
for i = 1:mat(1)
for j = 1:mat(2)
if pict(i, j) <= thresh
pict(i, j) = 1;
else
pict(i, j) = 0;
end
end
end
imwrite(pict, "threshold.bmp");

Thursday, June 19, 2008

Area Estimation for Images

In this activity, we tried to measure the size, in pixel count, of some regular shapes.
We used the SIP toolbox in scilab to load the images then we used Green's theorem to approximate pixel area of the drawn shapes. The SIP command "follow" was used to obtain the contour that was used in Green's theorem. To see if the approximations were accurate, I used a simple pixel count of the image. (1 corresponds to white and 0 to black, so the sum corresponds to the pixel area).
The obtained area using Green's theorem and pixel counts were:
100x100 square:
greens = 9801.
pixelcount = 10000.

50 pixel radius triangle:
greens = 7567.
pixelcount = 7708.

100x100(base x height) triangle:
greens = 4704.5
pixelcount = 4851.

100x150 rectangle:
greens = 14751.
pixelcount = 15000.

The obtained results were quite accurate.
For this activity, I give myself a grade of 9 since I think I performed the activity quite well. Raf also helped me with some scilab codes.

Scilab code used:
im1 = imread("100x150rect.bmp");
im1 = im2bw(im1, 1);
[x, y] = follow(im1);
sx = size(x);
sy = size(y);
sx = sx(1);
sy = sy(1);
x1 = x;
y1 = y;

x1(1) = x(sx);
x1(2:sx) = x(1:(sx-1));
y1(1) = y(sy);
y1(2:sy) = y(1:(sy-1));

xy1 = x.*y1;
yx1 = y.*x1;

greens = abs(0.5*sum(xy1-yx1))

pixelcount = sum(im1)

Thursday, June 12, 2008

Digital Scanning

Pixel counts to Physical units:
x-axis: 36 pixels = 5
y-axis: 75 pixels = 100

The pixel locations obtained in Paint were adjusted so that the (0,0) value in the plot would correspond to the (0,0) pixel location. To convert the pixel value to the physical unit, I just used ratio and proportion.
For the x-axis: [(x pixel location)/36]*5
y-axis: [(y pixel location)/75]*100

The reconstructed plot along with the original plot is shown below(plotted in open office calc using a bitmap chart area and transparent chart wall):
For this work, I give myself 10/10 since the obtained reconstruction was accurate.