4

Is there simple solution to add motion blur to an image in Qt? Haven't found any good tutorial about blur. I need something really simple, that I could understand, and would really good if I could change blur angles.

Mat
  • 202,337
  • 40
  • 393
  • 406
Julius Degutis
  • 276
  • 1
  • 3
  • 11
  • Qt itself doesn't have a motion blur effect AFAIK. The QGraphicsBlurEffect is a simple blur with a radius. You could however have a look at [this link](http://http.developer.nvidia.com/GPUGems3/gpugems3_ch27.html), ignoring the section on depth if you want an even blur within the image plane. Perhaps you can then create your own QGraphicsEffect. – Bart May 20 '12 at 16:26

1 Answers1

2

Qt hasn't a motion blur filter. I looked at the code of QGraphicsBlurEffect; it uses QPixmapBlurEffect which itself uses an internal helper method called expblur (exponential blur).

expblur itself uses a one-dimensional blur effect (motion blur in X direction, method qt_blurrow) twice. It rotates the image between the two blurs by 90 degrees and afterwards rotates it back.

So actually, Qt has a motion blur effect but this is internal only. So you need to write your own effect. To do so, have a look at the code of qt_blurrrow, which you can find in the Qt sources at src/gui/qpixmapfilter.cpp. This will give you a good quality for the filter, since it is an exponential blur filter instead of a linear one.

If you don't want to go so deep into the Qt source code, take this pseudo-code as a start:

foreach pixel (x, y) in image {
    for dx = -r to r with x+dx within image {
        for dy = -r to r with y+dy within image {
            Add pixel (x+dx, y+dy) of the source image with ↩
            factor (matrix[dx, dy]) to the target image.
        }
    }
}

where matrix might be defined like this (for horizontal motion blur with radius 2):

0   0   0   0   0
0   0   0   0   0
0.1 0.2 0.4 0.2 0.1
0   0   0   0   0
0   0   0   0   0

Notice that the sum of all entries has to be 1, or you have to divide the colors by the sum of the matrix entries.

Building this matrix for a given radius r and angle α is difficult when you want to allow arbitrary angles for α (not only 90 degrees steps). [EDIT: See comment 3 for an easy generation of such a matrix.]

leemes
  • 44,967
  • 21
  • 135
  • 183
  • If I good remember, this matrix is convolve matrix. Used it on java, and then I needed blur by all angles, then I rejected it as a possibility. But can't find anything better. But this that matrix I can get more angles than 90 steps. For example make 45 steps angles, just difference matrix members will be with not zeros? for example `x 0 0 0 0 0 x 0 0 0 0 0 x 0 0 0 0 0 x 0 0 0 0 0 x ` am I right? 45 degrees blur? – Julius Degutis May 20 '12 at 21:20
  • Yes, this would be 45 degrees. But if every x in your example matrix is the same (constant) number, it would be a linear blur, which looks unnatural. For better quality, you should use a linear function for a square blur (http://www.wolframalpha.com/input/?i=1-abs%28x%29+for+-1%3Cx%3C1). I don't know the maths behind an exponential blur, but I expect an exponential function ;) But I think the linear function for square blur is enough. – leemes May 20 '12 at 21:28
  • Ah, I forgot to say: To generate a matrix, you could cheat a bit: Just let Qt draw a white line in a small black image ((2r+1) * (2r+1) pixels). Of course, you should enable anti-aliasing. For the linear function thing, you could apply a radial gradient pattern afterwards (dark on the outer, transparent on the inner end). That gives you exactly the matrix as described in my previous comment (grey values of the pixels). ;) – leemes May 20 '12 at 21:33