##### Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

# Motion Blur Effect (Nokia Imaging SDK)

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

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)

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

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