Thursday, June 5, 2008

Assignment 8

1. Scaling in the x and y directions by different factors.
The Matlab M-file:
function [ smim ] = shrink2dir( picture, fu,fv)
picture = double(picture);
Mp=floor(size(picture,1)*fu);
Np=floor(size(picture,2)*fv);
smim(:,:,1)=zeros(Mp,Np);
smim(:,:,2)=zeros(Mp,Np);
smim(:,:,3)=zeros(Mp,Np);
for i=0:(Mp-1);
for j=0:(Np-1);
for x=(floor(i/fu):ceil((i+1)/fu)-1);
for y=(floor(j/fv):ceil((j+1)/fv)-1);
ival=picture(x+1,y+1,:);
if (x<(i/fu));
ival=ival*(1-(i/fu)+x);
end;
if ((x+1)>(i+1)/fu);
ival=ival*(1-(x+1)+((i+1)/fu));
end;
if (y<(j/fv));
ival=ival*(1-(j/fv)+y);
end;
if ((y+1)>(j+1)/fv);
ival=ival*(1-(y+1)+((j+1)/fv));
end;
smim(i+1,j+1,:)=smim(i+1,j+1,:)+ival;
end;
end;
end;
end;
smim=smim*fu*fv;
imshow(double(smim)/255);
end
Sample command:
A = imread('grasshopper.jpg');
B = shrink2dir(A, 1, 0.5)














a) f_x = 1, f_y =0.5



















b) f_x = 0.5, f_y = 1









c) f_x = 0.2, f_y = 0.8






2. Enlarge using nearest neighbour approximation.

function [largeimage] = enlargenn( picture, f )
picture=double(picture);
Mp = floor(size(picture,1));
Np = floor(size(picture,2));
largeimage(:,:,1)=zeros(f*Mp,f*Np);
largeimage(:,:,3)=zeros(f*Mp,f*Np);
largeimage(:,:,2)=zeros(f*Mp,f*Np);
for i = 0:(f*Mp-1);
for j = 0:(f*Np-1);
largeimage(i+1,j+1,:)=picture(round((i+1)/f),round((j+1)/f),:);
end;
end;
largeimage=largeimage/255;

Example of Matlab commands:
rainbow=imread('rainbow.jpg');
A=shrink2(rainbow,0.75); %this is M-file from A7
B=enlargenn(A,4/3);
image(B*255)








































































































































5. Shrinking an image 4x over (this one was fun!)














I used the nearest neighbour method from assignment 7:

function [ smim2 ] = shrink2( picture, f )
Mp = floor(size(picture,1)*f);
Np = floor(size(picture,2)*f);
smim2(:,:,1)=zeros(Mp,Np);
smim2(:,:,2)=zeros(Mp,Np);
smim2(:,:,3)=zeros(Mp,Np);
for i = 0:(Mp-1);
for j = 0:(Np-1);
a=round(i/f);
b=round(j/f);
smim2(i+1,j+1,:)=picture(a+1,b+1,:);
end;
end;
smim2= (smim2)/255;

and then the commands:
pic=imread('blueyellow.jpg');
pic20=shrink2(pic,0.2);
pic40=shrink2(pic,0.4);
pic60=shrink2(pic,0.6);
pic80=shrink2(pic,0.8);
pic(52:(52+409-1),77:(77+614-1),:)=pic80*255;
pic(103:(103+307-1),154:(154+460-1),:)=pic60*255;
pic(154:(154+204-1),231:(231+307-1),:)=pic40*255;
pic(205:(205+102-1),308:(308+153-1),:)=pic20*255;
imshow(pic)

Assignment 7 - Comments and Method 4

Method 4 - Bicubic interpolation and comparison of methods

According to the textbook (p. 66), this method is preferred over the bilinear interpolation method since it "does a better job of preserving fine detail". In fact, Matlab uses bicubic interpolation as its default method for the built-in image size reduction function. Also, as the textbook notes, bicubic interpolation is the method used in commerical image editing programs like Photoshop (and presumably GIMP).

However, since bicubic interpolation involves using the 16 nearest neighbours of a point (x, y) to determine the intensity value at (i, j) on the smaller image, the computation time is slower when compared with the bilinear interpolation and nearest neighbour methods. Several websites also describe complications with how to handle the edge/border points when writing programs using bicubic interpolation, so I won't be attempting this. But for illustration purposes, I will use Matlab's imresize function (which by default is using bicubic interpolation) to compare the quality of images using the different methods.


Here's what Matlab says about methods 2, 3 and 4 (apparently, method 1 is so terrible that nobody else seems to mention this method):


Nearest-neighbor interpolation: the output pixel is assigned the value of the pixel that the point falls within. No other pixels are considered. This is the fastest method, but has the lowest quality.

Bilinear interpolation: the output pixel value is a weighted average of pixels in the nearest 2-by-2 neighborhood

Bicubic interpolation: the output pixel value is a weighted average of pixels in the nearest 4-by-4 neighborhood. This is the slowest method, but has the highest quality.


Looking at some images: These use scale factor f=0.75














1) Method 1: Averaging












2) Method 2: Nearest Neighbour (using my commands)










3) Method 3: Bilinear interpolation (using my commands)










Based on these images, it seems as though method 3 preserves the most detail from the original image, and method 1 the least.

4) Method 4: Bicubic interpolation (using Matlab's imresize function)















It's a bit hard to compare these images because of the scaling on the ones created using my commands. Here is a more direct comparison of the methods using imresize for methods 2, 3 and 4 (with f = 0.25):








































It seems that both bilinear and bicubic provide images that are closer to the original than the nearest neighbour method, with bicubic a bit better than bilinear.

Assignment 7 - Method 3

3. Shrink using bilinear interpolation.

The Matlab M-file:
function [ smim3 ] = shrink3( picture, f )
picture=double(picture);
Mp = floor(size(picture,1)*f);
Np = floor(size(picture,2)*f);
for i = 0:(Mp-1);
for j = 0:(Np-1);
a=(i/f);
b=(j/f);
r=floor(a);
s=floor(b);
if (r>0) && (r<256)>0) && (s<256);
for k=1:3;
smim3(i,j,k)=[1-a+r, a-r]*[picture(r,s,k), picture(r,s+1,k); picture((r+1),s,k), picture((r+1),(s+1),k)]*[1-b+s; b-s];
end;
end;
end;
end;
smim3=smim3/255;

The Matlab commands (as an example)
rainbow=imread('rainbow.jpg');
image(shrink3(rainbow,0.75))
image(shrink3(rainbow,0.25))
image(shrink3(rainbow,0.1))

































































































































































Tuesday, June 3, 2008

Assignment 7 - Method 2

Method 2: Shrinking using the nearest neighbour.

Here's the Matlab M-file:

function [ smim2 ] = shrink2( picture, f )
Mp = floor(size(picture,1)*f);
Np = floor(size(picture,2)*f);
smim2(:,:,1)=zeros(Mp,Np);
smim2(:,:,2)=zeros(Mp,Np);
smim2(:,:,3)=zeros(Mp,Np);
for i = 0:(Mp-1);
for j = 0:(Np-1);
a=round(i/f);
b=round(j/f);
smim2(i+1,j+1,:)=picture(a+1,b+1,:);
end;
end;
smim2= (smim2)/255;


The Matlab commands (eg. for rainbow)

rainbow=imread('rainbow.jpg');
image(shrink2(rainbow,0.75))
image(shrink2(rainbow,0.25))
image(shrink2(rainbow,0.1))












































































































Assignment 7 - Method 1

1. Method 1: Average over all pixels in the destination point.

The Matlab M-file:
function [ smim ] = shrink( picture, f )
Mp = floor(size(picture,1)*f);
Np = floor(size(picture,2)*f);
smim(:,:,1)=zeros(Mp,Np);
smim(:,:,2)=zeros(Mp,Np);
smim(:,:,3)=zeros(Mp,Np);
for i = 0:(Mp-1)
for j = 0:(Np-1)
for x = floor(i/f):ceil((i+1)/f)-1
for y = floor(j/f):ceil((j+1)/f)-1
ival = picture(x+1,y+1,:);
ival = double(ival);
if(x<(i/f));
ival =ival*(1+x-i/f);
end;
if (x+1 > (i+1)/f);
ival = ival*(1+((i+1)/f)-(x+1));
end;
if (y< (j/f));
ival = ival*(1-(j/f)+y);
end;
if (y+1 > (j+1)/f);
ival = ival*(1-(y+1)+(j+1)/f);
end;
smim(i+1,j+1,:) = smim(i+1,j+1,:)+ival;
end;
end;
smim(i+1,j+1,:) = smim(i+1,j+1,:)/(1/f)^2;
smim = smim/255;
end;
end;

The Matlab commands (I'll just show them for the rainbow; the others are similar)

rainbow=imread('rainbow.jpg');
image(shrink(rainbow,0.75))
image(shrink(rainbow,0.25))
image(shrink(rainbow,0.1))