1

I have Java code that takes a convolution matrix (just a 2D double[][]) and applies it to an image. I'm trying to figure out how to create a matrix that will give a motion blur, given an angle (in degrees) and a magnitude for the blur.

An example matrix for a blur with magnitude = 1 (the middle pixel is blurred by one pixel in each direction), 45 degree motion blur is:

0      0    1/3
0     1/3    0
1/3    0     0

The magnitude determines the size of the matrix (size = 2*magnitude + 1) and a single line of cells is non-zero in the direction of motion.

What I'm having trouble with is the math/code necessary to figure out which cells to have non-zero in the matrix given the angle.

Pseudo (or actual) code would be immensely helpful!

scaevity
  • 3,991
  • 13
  • 39
  • 54

2 Answers2

1

For a motion blur the non-zero elements show all lie along a single line. That's why your example works. [1/n 1/n (ntimes)... 1/n] would blur in the horizontal direction while the transpose would blur vertically. For an arbitrary angle just fill in the non-zero elements that best approximate a line at the angle you want.

edit.

For example, you might try to minimize some function of the pixel indices to determine whether that pixel should be non-zero. |(i - 3*j)| < small number, would find pixels along a line of slope 3.

bogle
  • 274
  • 1
  • 4
1

In Matlab and Octave, there is a build in function called "fspecial" for creating kernels for convolution. By passing the 'motion' flag along with the magnitude and angle, it will output a constitutional kernel (matrix) that you can use to apply motion blur to your image. https://octave.sourceforge.io/image/function/fspecial.html

Unfortunately, there does not appear to be such a function in other languages, that I can find anyway for creating this kernel. The best that I can think of is to convert the angle and magnitude into the start and end (x,y) points of a line. Then you could draw a grayscale, anti-aliased line using Xiaolin Wu algorithm https://rosettacode.org/wiki/Xiaolin_Wu%27s_line_algorithm

You would have to divide all the elements by the sum of the elements to ensure that the kernel is normalised before convolving it with your image.