Friday, June 20, 2008

Mosaic Code

I used the 27 images below to get the mosaic. Actually since I did not really color match the pictures, I could have used any reasonable number, if my array had 1000 different pictures or 10 different pictures, it would still find the closest average color to the pixel being replaced. The important thing would be to pick enought pictures with different colors.
To shrink the images to a certain n by n size I used

function [ smim ] = shrinknm( picture,n, m)
fy = double(n)/double(size(picture,1));
fx = double(m)/double(size(picture,2));
Mp = floor(size(picture,1)*fy);
Np = floor(size(picture,2)*fx);
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/fy):ceil((i+1)/fy)-1
for y = floor(j/fx):ceil((j+1)/fx)-1
ival = picture(x+1,y+1,:);
if(x less than i/fy)
ival =ival*(1+x-i/fy);
end
if (x+1 greater than (i+1)/fy)
ival = ival*(1+((i+1)/fy)-(x+1));
end
if (y less than j/fx)
ival = ival*(1-(j/fx)+y);
end
if (y+1 > (j+1)/fx)
ival =ival*(1-(y+1)+(j+1)/fx);
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/fx)/(1/fy);
end
end


I saved the following script for reading in pictures in a text file to be reused:



a1 = imread('a1.jpg');
a2 = imread('a2.jpg');
a3 = imread('a3.jpg');
a4 = imread('a4.jpg');
a5 = imread('a5.jpg');
a6 = imread('a6.jpg');
a7 = imread('a7.jpg');
a8 = imread('a8.jpg');
a9 = imread('a9.jpg');
a10 = imread('a10.jpg');
a11 = imread('a11.jpg');
a12 = imread('a12.jpg');
a13 = imread('a13.jpg');
a14 = imread('a14.jpg');
a15 = imread('a15.jpg');
a16 = imread('a16.jpg');
a17 = imread('a17.jpg');
a18 = imread('a18.jpg');
a19 = imread('a19.jpg');
a20 = imread('a20.jpg');
a21 = imread('a21.jpg');
a22 = imread('a22.jpg');
a23 = imread('a23.jpg');
a24 = imread('a24.jpg');
a25 = imread('a25.jpg');
a26 = imread('a26.jpg');
a27 = imread('a27.jpg');
a28 = imread('a28.jpg');
a29 = imread('a29.jpg');
a30 = imread('a30.jpg');
a31 = imread('a31.jpg');
a32 = imread('a32.jpg');
b1 = floor(shrinknm(double(a1),30,30)/86)*86+42;
b2 = floor(shrinknm(double(a2),30,30)/86)*86+42;
b3 = floor(shrinknm(double(a3),30,30)/86)*86+42;
b4 = floor(shrinknm(double(a4),30,30)/86)*86+42;
b5 = floor(shrinknm(double(a5),30,30)/86)*86+42;
b6 = floor(shrinknm(double(a6),30,30)/86)*86+42;
b7 = floor(shrinknm(double(a7),30,30)/86)*86+42;
b8 = floor(shrinknm(double(a8),30,30)/86)*86+42;
b9 = floor(shrinknm(double(a9),30,30)/86)*86+42;
b10 = floor(shrinknm(double(a10),30,30)/86)*86+42;
b11 = floor(shrinknm(double(a11),30,30)/86)*86+42;
b12 = floor(shrinknm(double(a12),30,30)/86)*86+42;
b13 = floor(shrinknm(double(a13),30,30)/86)*86+42;
b14 = floor(shrinknm(double(a14),30,30)/86)*86+42;
b15 = floor(shrinknm(double(a15),30,30)/86)*86+42;
b16 = floor(shrinknm(double(a16),30,30)/86)*86+42;
b17 = floor(shrinknm(double(a17),30,30)/86)*86+42;
b18 = floor(shrinknm(double(a18),30,30)/86)*86+42;
b19 = floor(shrinknm(double(a19),30,30)/86)*86+42;
b20 = floor(shrinknm(double(a20),30,30)/86)*86+42;
b21 = floor(shrinknm(double(a21),30,30)/86)*86+42;
b22 = floor(shrinknm(double(a22),30,30)/86)*86+42;
b23 = floor(shrinknm(double(a23),30,30)/86)*86+42;
b24 = floor(shrinknm(double(a24),30,30)/86)*86+42;
b25 = floor(shrinknm(double(a25),30,30)/86)*86+42;
b26 = floor(shrinknm(double(a26),30,30)/86)*86+42;
b27 = floor(shrinknm(double(a27),30,30)/86)*86+42;
b28 = floor(shrinknm(double(a28),30,30)/86)*86+42;
b29 = floor(shrinknm(double(a29),30,30)/86)*86+42;
b30 = floor(shrinknm(double(a30),30,30)/86)*86+42;
b31 = floor(shrinknm(double(a31),30,30)/86)*86+42;
b32 = floor(shrinknm(double(a32),30,30)/86)*86+42;
imshow(b1/255);
imshow(b2/255);
imshow(b3/255)
imshow(b4/255)
imshow(b5/255)
imshow(b6/255)
imshow(b7/255)
imshow(b8/255)
imshow(b9/255)
imshow(b10/255)
imshow(b11/255)
imshow(b12/255)
imshow(b13/255)
imshow(b14/255)
imshow(b15/255)
imshow(b16/255)
imshow(b17/255)
imshow(b18/255)
imshow(b19/255)
imshow(b20/255)
imshow(b21/255)
imshow(b22/255)
imshow(b23/255)
imshow(b24/255)
imshow(b25/255)
imshow(b26/255)
imshow(b27/255)
imshow(b28/255)
imshow(b29/255)
imshow(b30/255)
imshow(b31/255)
imshow(b32/255)

A = {b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 b16 b17 b18 b19 b20 b21 b22 b23 b24 b25 b26 b27};

Wednesday, June 18, 2008

Mosaic

Original.



So I finally decided to start on the mosaic today but after looking through thousands of pictures I have taken myself, I realized that none of them would look good at the resolution we are using. So given that cartoons have solid colors and simple shapes, and the fact that I do enjoy watching them sometimes, I chose to create a mosaic of cartoons. I went to google images and did a search for cartoons. Then I selected about forty or so. My criteria was that they had to be very simple and have a limited amount of colors, and be a chararter I recognized. After shrinking them to a 30 by 30 size, I eliminated some of them because they became unrecognizable at that resolution. For the main image I chose a picture of Cartman because I figured even at low resolution he is pretty recognizable. I did not bother trying to pick pictures with average colors resembling the 27 colors we have, I just tried to pick enough different colors for the pictures. Since the shapes are so simple, even if the colors do not match well, it will still be very recognizable.

To match the colors I first tried to use the minimum absolute difference between the pixel color and the average color of each image, but the images I got were not as good as I wanted.

function [ inpic ] = mosaic( inpic,A )

for i=1:27
av(1,i,:) = sum(sum(A{i}))/900;
end


for k = 1:size(inpic,1)/30
for l=1:size(inpic,2)/30
pixel = inpic(30*k,30*l,:);
b=200000;
place = 1;
for i=1:27
dif = sum(abs(av(1,i,:)-pixel));
% ds = abs(av(1,i,:)-pixel);
% dif = ds(:,:,1)^2+ds(:,:,2)^2+ds(:,:,3)^2;
if (dif b = dif;
place = i;
end
end

inpic(30*k-29:30*k,30*l-29:30*l,:)=A{place};
end
end
end












Then I thought about standard deviation, and how we need to get the sum of the squared differences. I have always wondered about why not just get the sum of absolute differences, and I think this is a nice visual example of why this works better. Because having one of the three colors off significantly is worse than having 3 colors off a little, and same with points in a data set. I thought this relationship between Statistics and matching colors is pretty cool. So I used:







function [ inpic ] = mosaic( inpic,A )
for i=1:27
av(1,i,:) = sum(sum(A{i}))/900;
end
for k = 1:size(inpic,1)/30
for l=1:size(inpic,2)/30
pixel = inpic(30*k,30*l,:);
b=200000;
place = 1;
for i=1:27
%dif = sum(abs(av(1,i,:)-pixel));
ds = abs(av(1,i,:)-pixel);
dif = ds(:,:,1)^2+ds(:,:,2)^2+ds(:,:,3)^2;
if (dif less than b)
b = dif;
place = i;
end
end
inpic(30*k-29:30*k,30*l-29:30*l,:)=A{place};
end
end
end











I also like this method of choosing colors, because it is easily expandable to 64 and more colors. All I have to do is keep on adding images into the array, I could theoretically add as many as I want and it will do the matching for me.

I have to go to class now, will add the code later.

Wednesday, June 11, 2008

Assignment 10 fabio

function [ outpic ] = swirlbw( inpic,gamma,rad )

cx = size(inpic,1)/2;
cy = size(inpic,2)/2;
outpic=zeros(size(inpic,1),size(inpic,2));

for x =1:size(inpic,1)
for y=1:size(inpic,2)
d= sqrt((x-cx)^2+(y-cy)^2);
if ((d gt rad) or (d lt 1))
outpic(x,y) = inpic(x,y);
else if (y lt cy)
theta = acos((x-cx)/d);
else
theta = -acos((x-cx)/d);
end
fr =((d/rad)^2)*(1-d/rad)^2*16;
newx = d*cos(theta+gamma*fr)+cx;
newy = d*sin(theta+gamma*fr)+cy;
a=newx;
b=newy;
r=floor(newx);
s=floor(newy);

outpic(x,y)= [1-a+r a-r]*[inpic(r,s) inpic(r,s+1);inpic(r+1,s) inpic(r+1,s+1)]*[1-b+s; b-s];

end
end
end


Assignment 10 aniston




function [ outpic ] = unswirl( inpic,gamma,rad )
cx = size(inpic,1)/2;
cy = size(inpic,2)/2;
outpic(:,:,1)=zeros(size(inpic,1),size(inpic,2));
outpic(:,:,2)=zeros(size(inpic,1),size(inpic,2));
outpic(:,:,3)=zeros(size(inpic,1),size(inpic,2));
for x =1:size(inpic,1)
for y=1:size(inpic,2)
d= sqrt((x-cx)^2+(y-cy)^2);
if ((d gt rad) or (d lt 1))
outpic(x,y,:) = inpic(x,y,:);
else if (y lt cy)
theta = acos((x-cx)/d);
else
theta = -acos((x-cx)/d);
end
fr =((d/rad)^2)*(1-d/rad)^2*16;
newx = d*cos(theta+gamma*fr)+cx;
newy = d*sin(theta+gamma*fr)+cy;
a=newx;
b=newy;
r=floor(newx);
s=floor(newy);
for k=1:3
outpic(x,y,k)= [1-a+r a-r]*[inpic(r,s,k) inpic(r,s+1,k);inpic(r+1,s,k) inpic(r+1,s+1,k)]*[1-b+s; b-s];
end
end
end
end






Tuesday, June 10, 2008

Assignment 9 question 1

Take the images from Assignment 6 number #3 part (c) and
convert them to an image with only 64 colors.


>> B = floor(bluelines/64)*85;
>> imshow(B);



>> B = floor(jade/64)*85;
>> imshow(B);

>> B = floor((jade+42)/85)*85;
>> imshow(B);


>> B = floor((bluelines+42)/85)*85;
>> imshow(B);




Assignment 9 question 2

Take the images from Assignment 6 number #3 part (c) and convert
them to an image with only 27 colors.

>> B = floor((bluelines+64)/128)*128;
>> imshow(B);





>> B = floor((jade+64)/128)*128;
>> imshow(B);


>> B = floor((jade)/86)*128;
>> imshow(B);



>> B = floor((bluelines)/86)*128;

>> imshow(B);


Assignment 9 Question 3

Take the images from Assignment 6 number #3 part
(c) and turn them into a greyscale image (with values between 0 and 255). Do this
by computing the intensity of each pixel in the image.


function [ gim ] = togray( cim )

gim = (cim(:,:,1)+cim(:,:,2)+cim(:,:,3))/3;

>> imshow(togray(bluelines/255));


>> imshow(togray(jade/255));

Assignment 9 question 4

Take the images from Assignment 6 number
#3 part (c) and turn them into a greyscale image with only 64 intensity values.
Use values between 0 and 252 but that are divisible by 4.

>> B = togray(jade);
>> C = floor(B/4)*4;
>> imshow(C/255)


>> B = togray(bluelines);
>> C = floor(B/4)*4;
>> imshow(C/255)

Assignment 9 question 5


Take the images from Assignment 6 number #3 part (c)
and turn them into a greyscale image with only 16 intensity values. Use values
between 0 and 240 but that are divisible by 16.

>> B = togray(bluelines);
>> C = floor(B/16)*16;
>> imshow(C/255)

>> B = togray(jade);
>> C = floor(B/16)*16;
>> imshow(C/255)

Assignment 8 question 1

Modify Assignment 7 problem #1 so that you can scale in the x and y directions
by different factors. Scale one of the two pictures that you downloaded of the web

function [ smim ] = shrinkxy( picture,fx, fy )
Mp = floor(size(picture,1)*fy);
Np = floor(size(picture,2)*fx);

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/fy):ceil((i+1)/fy)-1
for y = floor(j/fx):ceil((j+1)/fx)-1
ival = picture(x+1,y+1,:);
if(x ival =ival*(1+x-i/fy);
end
if (x+1 > (i+1)/fy)
ival = ival*(1+((i+1)/fy)-(x+1));
end
if (y< j/fx)
ival = ival*(1-(j/fx)+y);
end
if (y+1 > (j+1)/fx)
ival =ival*(1-(y+1)+(j+1)/fx);
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/fx)/(1/fy);
end
end

>> imshow(shrinkxy(bluelines,1,0.5))
>> imshow(shrinkxy(bluelines,0.5,1))
>> imshow(shrinkxy(bluelines,0.2,0.8))




Assignmet 8 Question 2

Enlarge the color images that you scaled down in assignment 7 using a factor of
1/f. Use the 'nearest neighbor' approximation.

function [largeimage] = enlargenn( picture, f )
picture=double(picture);
Mp = size(picture,1);
Np = 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 = 1:(f*Mp);
for j = 1:(f*Np );
if (i/f < 1 && j/f < 1)
largeimage(i,j,:)=picture(1,1);
end
if ((i/f < 1) && (j/f >= 1))
largeimage(i,j,:)=picture(1,round(j/f),:);
end
if ((i/f >= 1) && (j/f < 1))
largeimage(i,j,:)=picture(round(i/f),1,:);
end
if ((i/f>=1) && (j/f>=1))
largeimage(i,j,:)=picture(round((i)/f),round((j)/f),:);
end
end;
end;

>> B = shrink3(bluelines,0.1);
>> imshow(enlargenn(B,10))
>> B = shrink3(bluelines,0.25);
>> imshow(enlargenn(B,4))
>> B = shrink3(bluelines,0.75);
>> imshow(enlargenn(B,4/3))






Assignment 8 Question 3

Enlarge the color images that you scaled down in assignment 7 using a factor of
1/f. Use the bilinear interpolation approximation.

function [ largeimage ] = enlargebi( picture, f )
picture=double(picture);
Mp = size(picture,1);
Np = size(picture,2);

for i = 1:(f*Mp);
for j = 1:(f*Np);
a=i/f;
b=j/f;
r=floor(a)+2;
s=floor(b)+2;
if s>0 && s<=size(picture,2) && r>0 && r<=size(picture,1)
for k=1:3;
largeimage(i,j,k)=[1-a+(r-2) a-(r-2)]*[picture(r-1,s-1,k) picture(r-1,s,k); picture(r,s-1,k) picture(r,s,k)]*[1-b+(s-2); b-(s-2)];
end;
end;
end;

end;

>> B = shrink(bluelines,0.1);
>> imshow(enlargebi(B,10))
>> B = shrink(bluelines,0.25);
>> imshow(enlargebi(B,4))
>> B = shrink(bluelines,0.75);
>> imshow(enlargebi(B,4/3))






Assignment 8 Question 4


Question 4.
Now that you have experimented a bit, which method (or combination of methods)
of shrinking and enlarging images is most effective at preserving the resolution?
Explain why you feel that way by pointing to examples.
Try to determine what GIMP/Photoshop does when it scales images.


Technically they all have the same resolution. I am not sure if we are talking about detail, contrast or overall likeness to the original image. I think if we are looking at detail and contrast then some combination of nearest neighbour and bilinear interpolation will be the best, because nearest neighbour does not reduce the contrast of the original pixels at all. It also seems to retain more detail. The bilinear interpolation is also good at retaining more contrast and detail. On the other hand they produce choppy images that get worse as the factor increases. The average color method produces images that are blurry and have a lower contrast but are much closer to the original in overall likeness.


The following four images compare different methods to shrink and expand by a factor of four. The first is the original, the second uses bilinear shrink and expand, the third uses nearest neighbour shrink and bilinear expand, the fourth uses average shrink and bilinear expand. The fourth is the closest to the original in overall likeness.








When using GIMP we have the option of nearest neighbour resizing , Linear interpolation,
Cubic interpolation or something called Sinc (Lanczos 3)

Assignment 8 question 5



function [ im ] = shrinkpaste( pic,k ,f)
im = pic;
temp = pic;
Np = size(pic,1);
Mp = size(pic,2);
for i = 1:k
temp = shrink(temp,f);
n = size(temp,1);
m = size(temp,2);
stn = round(Np/2 - n/2);
stm = round(Mp/2 - m/2);
im(stn:stn+n-1,stm:stm+m-1,:)=temp;
end
end
>> imshow(shrinkpaste(start,4,0.75))

Wednesday, June 4, 2008

Assignment 7

(1)Sub-square average shrink

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,:);
if(x (i+1)/f)
ival = ival*(1+((i+1)/f)-(x+1));
end
if (y< ival =" ival*(1-(j/f)+y);"> (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;
end
end


(2) Nearest pixel shrink

function [ smim ] = shrink2( picture,f )

Mp = floor(size(picture,1)*f);
Np = floor(size(picture,2)*f);

for i = 1:Mp
for j = 1:Np
a = round(i/f);
b = round(j/f);
smim(i,j,:) = picture(a,b,:);
end
end

(3) Bilinear interpolation shrink

function [ smim ] = shrink3( picture,f )
Mp = floor(size(picture,1)*f);
Np = floor(size(picture,2)*f);

for i = 1:Mp
for j = 1:Np
a = i/f;
b = j/f;
r = floor(a);
s = floor(b);
if (r>0) && (r 0) && (s smim(i,j,1) = [1-(a-r),a-r]*[picture(r,s,1), picture(r,s+1,1); picture(r+1,s,1),picture(r+1,s+1,1)]*[1-b+s;b-s];
smim(i,j,2) = [1-(a-r),a-r]*[picture(r,s,2), picture(r,s+1,2); picture(r+1,s,2),picture(r+1,s+1,2)]*[1-b+s;b-s];
smim(i,j,3) = [1-(a-r),a-r]*[picture(r,s,3), picture(r,s+1,3); picture(r+1,s,3),picture(r+1,s+1,3)]*[1-b+s;b-s];
end
end
end
shrink selection

Comparing the following three selection it is clear that the second method produces an image with the highest contrast and worst color transitions(smoothness) , since nothing is averaged. The first method is the smoothest, but it has the lowest contrast. The third method is something in the middle between the first two.






shrink 2 selection





shrink 3 selection






I only included one scale factor 0.1 and 0.25 picture, since on the blog they all look the same. Even the 0.75 images look indistinguishable to me. Of course when I zoom in to the actual images there are differences.



imshow(shrink(Jade,0.75))

imshow(shrink2(Jade,0.75))

imshow(shrink3(Jade,0.75))







imshow(shrink(bluelines,0.75))

imshow(shrink2(bluelines,0.75))

imshow(shrink3(bluelines,0.75))


imshow(shrink(rainbow,0.75))


imshow(shrink2(rainbow,0.75))

imshow(shrink3(rainbow,0.75))