## 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.

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,

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.

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.

### 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.

### 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.

Thank you very much for reading.

Probably this blog’s greatest post I have read

Comment by bellek | 2011 October 17 |

That was some illuminating blog!

Comment by Canon D5000 | 2011 November 28 |

Considerably well written piece of writing!!!

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

Your code is helping to do my semester miniproject thnQ

Comment by pradeep | 2013 October 10 |