Thilina's Blog

I might be wrong, but…

Photo Effects using MATLAB 1.0

Last few days I edited some of my photos using Picasa 3. In this application I found some interesting effects which can be added to images such as pictures which you can use as Facebook profile pictures etc.

clip_image002

I was quite interested to know how they were implemented. However I came out with a small set of solutions developed by myself to archive similar results to Picasa. In this article I will share my solutions to implement “Soft Focus” and “Focal B&W” by Picasa and an effect bit similar to the “Vignetting Effect” say “Shading Effect”.

For all these three effects I created a weighting system from the specified pixel to the far most pixel of the image with the range of 0 to 1. By keeping this weighting as the domain (fn) then I designed another weighting function (f) over that which will keep the strength of my operations to the image pixels. I used a weighting function with the form,

clip_image004

clip_image006

This will be also saturate on ‘1’. The parameters radius and grade defines the strength and the area which will be free of the image operations. Above plot is the plot of weighting function f with radius = 3 and grade = 5. Please note that the attached m-scripts are not optimised for speed processing, so it will take some time to generate results. For this article, my test image is as below.

clip_image008

The domain is defined by the maximum distance to the edge of the image from the defined pixel is calculated as below.

h = figure; imshow(cast(img,'uint8'));
[X Y] = getpts(h);
c0 = floor(X(1));
r0 = floor(Y(1));
c_ = max(c0,(c-c0));
r_ = max(r0,(r-r0));
L = sqrt(r_^2 + c_^2);

The L will be the maximum distance of the image. And in operation, the distance to the active pixel is calculated and taken the ratio to the L. This will be the domain value of that pixel for the final weighting function.

Ln = sqrt((r0-i)^2 + (c0-j)^2);
fn = (L-Ln)./L;
f = (radius*fn^grade);
if(f>1)
  f=1;
end

Shading Effect

In this effect, pixel intensity of the image is multiplied by the result of weighting function in the pixel. This will result in reduction of the intensity with respect to the focus point. Sample code is as below.

clear all;
close all;
clc;
%% Set Parameters
radius = 2;
grade = 2;
scale = 0.5;
%% File Select
[FileName,PathName] = uigetfile({'*.jpg';'*.jpeg';'*.JPG'},'SelectImage');
file = [PathName,FileName];
img = cast(imresize(imread(file),scale),'double');
%% Focal point and processing parameters
[r c d] = size(img);
IMG = zeros(r,c,d);
h = figure; imshow(cast(img,'uint8'));
[X Y] = getpts(h);
c0 = floor(X(1));
r0 = floor(Y(1));
c_ = max(c0,(c-c0));
r_ = max(r0,(r-r0));
L = sqrt(r_^2 + c_^2);
close(h);
%% F plot
x = 0:0.00001:1;
y = radius*x.^grade;
p = find(y>1);
y(p) = 1;
h = figure; plot(x,y);
pause;
close(h);
%% Processing
for i = 1:r
  for j = 1:c
    Ln = sqrt((r0-i)^2 + (c0-j)^2);
    f = (L-Ln)./L;
    f = (radius*f^grade);
    if(f>1)
      f=1;
    end
    IMG(i,j,:) = f*img(i,j,:);
  end
end
%% Display
imG = cast(IMG,'uint8');
imshow(imG);

The resulting image is as below.

clip_image010

Soft Focus Effect

In this effect I used a Gaussian blur kernel to blur the image. The blur function is taken from the report of “Facial Blemish Removal using Canny Edge Detection and Gaussian Blurring” by Joseph Marino and Gregory Yoblin. It is the best ever Gaussian function I had ever used. I convolved the 7×7 blur kernel with 7×7 neighbourhood of the pixel in interest. The centre pixel value of the blur kernel was replaced by the result of weighting function. Convolving process is as below.

ker(3,3) = f;
ker = ker./(sum(sum(ker)));
mat = frame(i-3:i+3,j-3:j+3,:);
IMG(i-3,j-3,1) = sum(dot(ker,mat(:,:,1)));
IMG(i-3,j-3,2) = sum(dot(ker,mat(:,:,2)));
IMG(i-3,j-3,3) = sum(dot(ker,mat(:,:,3)));

The process sum(dot(ker,mat)) defines the convolution of two kernels for single pixel. Sample code for the whole process is as below. The parameter strength defines the standard deviation of the Gaussian function.

clear all;
close all;
clc;
%% Parameters
strength = 5;
radius = 4;
grade = 5;
scale = 0.25;
%% file select
[FileName,PathName] = uigetfile({'*.jpg';'*.jpeg';'*.JPG'},'SelectImage');
file = [PathName,FileName];
img = cast(imresize(imread(file),scale),'double');
[r c d] = size(img);
IMG = zeros(r,c,d);
%% Focus spot
h = figure; imshow(cast(img,'uint8'));
[X Y] = getpts(h);
c0 = floor(X(1));
r0 = floor(Y(1));
c_ = max(c0,(c-c0));
r_ = max(r0,(r-r0));
L = sqrt(r_^2 + c_^2);
close(h);
%% Oepration
sigma = strength;
mask = gaussianMask(sigma);
[l m] = size(mask);
l = floor(l/2);
m = floor(m/2);
ker = mask(l-3:l+3,m-3:m+3);
ker = ker./(sum(sum(ker)));
frame = zeros(r+6,c+6,d);
frame(4:3+r,4:3+c,:) = img;
for i = 4:r+3
  for j = 4:c+3
    Ln = sqrt((r0-i)^2 + (c0-j)^2);
    f = (L-Ln)./L;
    f = (radius*f^grade);
    if (f>1)
      f=1;
    end
    ker(3,3) = f;
    ker = ker./(sum(sum(ker)));
    mat = frame(i-3:i+3,j-3:j+3,:);
    IMG(i-3,j-3,1) = sum(dot(ker,mat(:,:,1)));
    IMG(i-3,j-3,2) = sum(dot(ker,mat(:,:,2)));
    IMG(i-3,j-3,3) = sum(dot(ker,mat(:,:,3)));
  end
end
imG = cast(IMG,'uint8');
imshow(imG);

The Gaussian function taken from the report of Joseph Marino and Gregory Yoblin is as below.

function mask = gaussianMask(sigma)
loLim=-ceil(3*sigma); % lower limit
hiLim=ceil(3*sigma); % upper limit
x=loLim:hiLim;
y=loLim:hiLim;
for i=1:((hiLim-loLim)+1) % x
  for j=1:((hiLim-loLim)+1) % y
    mask(i,j)=(1/(2*pi*sigma^2))*exp(-(x(i)^2+y(j)^2)/(2*sigma^2)); % blur
  end
end

The resulting image is as below.

clip_image011

Focal B&W Effect

Gray scale image can be represented in the RGB space by placing same values for RGB matrices. In this effect I replaced the RGB values with gray scale values with the ratio of f and(1-f) which is obtained by the weighting function.

Ln = sqrt((r0-i)^2 + (c0-j)^2);
fn = (L-Ln)./L;
f = (radius*fn^grade);
if f>1
  f = 1;
end
IMG(i,j,1) = (f*frame(i,j,1))+((1-f)*bwframe(i,j));
IMG(i,j,2) = (f*frame(i,j,2))+((1-f)*bwframe(i,j));
IMG(i,j,3) = (f*frame(i,j,3))+((1-f)*bwframe(i,j));

This results in smooth variation of B&W values with RGB values with respect to the distance with pixel in interest.

clear all;
close all;
clc;
%% Parameters
scale = 0.5;
grade = 5;
radius = 1.7;
%% File select
[FileName,PathName] = uigetfile({'*.jpg';'*.jpeg';'*.JPG'},'SelectImage');
file = [PathName,FileName];
img = cast(imresize(imread(file),scale),'double');
[r c d] = size(img);
IMG = zeros(r,c,d);
%% Pick point in interest
h = figure; imshow(cast(img,'uint8'));
[X Y] = getpts(h);
c0 = floor(X(1));
r0 = floor(Y(1));
c_ = max(c0,(c-c0));
r_ = max(r0,(r-r0));
L = sqrt(r_^2 + c_^2);
close(h);
%% Operation
frame = img;
bwframe = cast(rgb2gray(cast(frame,'uint8')),'double');
for i = 1:r
  for j = 1:c
    Ln = sqrt((r0-i)^2 + (c0-j)^2);
    fn = (L-Ln)./L;
    f = (radius*fn^grade);
    if f>1
      f = 1;
    end
    IMG(i,j,1) = (f*frame(i,j,1))+((1-f)*bwframe(i,j));
    IMG(i,j,2) = (f*frame(i,j,2))+((1-f)*bwframe(i,j));
    IMG(i,j,3) = (f*frame(i,j,3))+((1-f)*bwframe(i,j));
  end
end
%% Display
imG = cast(IMG,'uint8');
imshow(imG);

Resulting image is as below.

clip_image013

Thank you very much for reading.

2011 June 18 - Posted by | Image Processing, MATLAB

4 Comments »

  1. Probably this blog’s greatest post I have read

    Comment by bellek | 2011 October 17 | Reply

  2. That was some illuminating blog!

    Comment by Canon D5000 | 2011 November 28 | Reply

  3. Considerably well written piece of writing!!!

    Comment by Seo Solution, Stanton Seo Service | 2011 December 14 | Reply

  4. Your code is helping to do my semester miniproject thnQ

    Comment by pradeep | 2013 October 10 | Reply


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: