×
Namespaces

Variants
Actions

Motion Blur Effect (Nokia Imaging SDK)

From Nokia Developer Wiki
Jump to: navigation, search

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

Article Metadata
Tested with
SDK: Windows Phone 8 SDK, Nokia Imaging SDK 1.2
Devices(s): Nokia Lumia 920
Article
Created: shai.i (14 Jul 2014)
Last edited: shai.i (14 Jul 2014)

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

This page was last modified on 14 July 2014, at 23:41.
104 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×