# Motion Blur Effect (Nokia Imaging SDK)

This article explains how to create a motion blur effect for images using a step increment.

Note: This is an entry in the Nokia Original Imaging Effect Wiki Challenge 2014Q2

## Contents |

## Introduction

The concept is to create an effect of capturing an image in the motion (its similar to an effect you would get if you try and take a picture of a fast moving object or using a slightly longer exposure)

The article includes the source code, instructions on how it can be used and tested and a sample result.

## Source code

The function below is the main function that does all the calculation and steps that use to create the motion (you can use translate, rotate & scale motion combination to create different effects as if the object was moving fast to the side or the object zoomed-in fast or rotated fast such as a moving ball that is thrown at the camera)

protected override void OnProcess(PixelRegion sourcePixelRegion, PixelRegion targetPixelRegion)

{

float centreX = 0.5f;

float centreY = 0.5f;

float cx = (float)sourcePixelRegion.Bounds.Width * centreX;

float cy = (float)sourcePixelRegion.Bounds.Height * centreY;

float imageRadius = (float)Math.Sqrt(cx * cx + cy * cy);

int height = (int)sourcePixelRegion.Bounds.Height;

sourcePixelRegion.ForEachRow((index, width, pos) =>

{

for (int x = 0; x < width; ++x, ++index)

{

float translateX = (float)(distance * Math.Cos(angle));

float translateY = (float)(distance * -Math.Sin(angle));

float scale = zoom;

float rotate = rotation;

float maxDistance = distance + Math.Abs(rotation * imageRadius) + zoom * imageRadius;

int steps = (int)Math.Log(maxDistance, 2);

translateX /= maxDistance;

translateY /= maxDistance;

scale /= maxDistance;

rotate /= maxDistance;

int y = index / width;

Matrix t;

Vector3 p = new Vector3();

uint temptemp = 0;

uint a = 0, r = 0, g = 0, b = 0;

int count = 0;

for (int i = 0; i < steps; i++)

{

int newX = x, newY = y;

float f = (float)i / steps;

p.X = x;

p.Y = y;

p.Z = 0;

t = Matrix.Identity;

t = Matrix.Multiply(t, Matrix.CreateTranslation(- cx + f * translateX, - cy + f * translateY, 0));

float s = scale * f;

//t = Matrix.Multiply(t, Matrix.CreateScale(s,s,0));

if (rotate != 0)

{

t = Matrix.Multiply(t, Matrix.CreateRotationZ(-rotate * f));

}

t = Matrix.Multiply(t, Matrix.CreateTranslation(cx, cy, 0));

p = Vector3.Transform(p, t);

newX = (int)p.X;

newY = (int)p.Y;

if (newX < 0 || newX >= width)

{

if (wrapEdges)

newX = mod(newX, width);

else

break;

}

if (newY < 0 || newY >= height)

{

if (wrapEdges)

newY = mod(newY, height);

else

break;

}

count++;

uint rgb = temptemp = sourcePixelRegion.ImagePixels[newY * width + newX];

a += (rgb >> 24) & 0xff;

r += (rgb >> 16) & 0xff;

g += (rgb >> 8) & 0xff;

b += rgb & 0xff;

translateX *= 2;

translateY *= 2;

scale *= 2;

rotate *= 2;

}

if (count == 0)

{

targetPixelRegion.ImagePixels[index] = sourcePixelRegion.ImagePixels[index];

}

else

{

a = (uint)Math.Max(0, Math.Min(255, ((int)(a / (float)count))));

r = (uint)Math.Max(0, Math.Min(255, ((int)(r / (float)count))));

g = (uint)Math.Max(0, Math.Min(255, ((int)(g / (float)count))));

b = (uint)Math.Max(0, Math.Min(255, ((int)(b / (float)count))));

uint temp = (a << 24) | (r << 16) | (g << 8) | b;

targetPixelRegion.ImagePixels[index] = temp;

}

}

});

}

## Performance

Since this is an effect and not a filter its obviously not fast and in fact its quite slow as it makes several passes per pixel (depending on the range of motion you intend to create) so its never meant to be used in real time preview.

## Testing the filter

The easiest way to test the effect is to download the real time viewer from GitHub. It is based on the Test Apps for Viewing Custom Filters (Nokia Imaging SDK) (itself a fork of the Real Time Filter Demo) but was adapted in order to allow for a fully custom pipeline.

## Sample picture

## Future work

In the future I hope to combine this with the foreground/background segmenter blur filter to make only a specific object in the image to have the motion effect. (also currently the different members parameters of this effect needs to be changed to a Property or have setters/getters since I used just private members for my tests).

## Loukt -

Hi Shai, I think you forgot to upload the sample pictures, !

(nice article btw)Loukt (talk) 02:26, 15 July 2014 (EEST)