简体   繁体   中英

extract motion blur of an image in matlab

I found that there are some paper said can analysis the gradient histogram (blur image has gradient follows a heavy-tailed distribution) or using fft (blur image has lower frequency) Is there a way to detect if an image is blurry? to detect blur in image.

But I am not quite sure how to implement it in matlab. How to define the threshold value and so on.

[Gx, Gy] = imgradientxy(a);
G = sqrt(Gx.^2+Gy.^2)

What should I do after running the command and find the G ? What should I do if I wanna plot a graph of number of pixel verse G

I am new to matlab and image processing. Could anyone kindly provide more details of how to implement it

Preparation: we read the cameraman image, which is often used for visualizing image processing algorithms, and add some motion blur.

origIm = imread('cameraman.tif');
littleBlurredIm = imfilter(origIm,fspecial('motion',5,45),'replicate');
muchBlurredIm = imfilter(origIm,fspecial('motion',20,45),'replicate');

which gives us the following images to start with:

开始图像

To calculate the Laplacian, you can use the imgradient function, which returns magnitude and angle, so we'll simply discard the angle:

[lpOrigIm,~] =  imgradient(origIm);
[lpLittleBlurredIm,~] = imgradient(littleBlurredIm);
[lpMuchBlurredIm,~] = imgradient(muchBlurredIm);

which gives:

过滤后的图像

You can visually see that the original image has very sharp and clear edges. The image with a little blur still has some features, and the image with much blur only contains a few non-zero values.

As proposed in the answer by nikie to this question , we can now create some measure for the blurriness. A (more or less) robust measure would for example be the median of the top 0.1% of the values:

% Number of pixels to look at: 0.1%
nPx = round(0.001*numel(origIm));

% Sort values to pick top values
sortedOrigIm = sort(lpOrigIm(:));
sortedLittleBlurredIm = sort(lpLittleBlurredIm(:));
sortedMuchBlurredIm = sort(lpMuchBlurredIm(:));

% Calculate measure
measureOrigIm = median(sortedOrigIm(end-nPx+1:end));
measureLittleBlurredIm = median(sortedLittleBlurredIm(end-nPx+1:end));
measureMuchBlurredIm = median(sortedMuchBlurredIm(end-nPx+1:end));

Which gives the following results:

 Original image: 823.7 Little Blurred image: 593.1 Much Blurred image: 490.3 

Here is a comparison of this blurriness measure for different motion blur angles and blur amplitudes.

模糊

Finally, I tried it on the test images from the answer linked above:

测试图像

which gives

模糊测试图像

Interpretation: As you see it is possible to detect, if an image is blurred. It however appears difficult to detect how strongly blurred the image is, as this also depends on the angle of the blur with relation to the scene, and due to the imperfect gradient calculation. Further the absolute value is very much scene-dependent, so you might have to put some prior knowledge about the scene into the interpretation of this value.

This is a very interesting topic. Although gradient magnitude can be used as good feature for blur detection but this feature will fail when dealing with uniform regions in images. In other words, this feature will not be able to distinguish between blur and flat regions. There are many other solutions. Some of them detect flat regions to avoid classifying flat regions as blur. if you want more information you can check these links:

You can find many good recent papers in cvpr conference. Many of them they have websites where they discuss the details and provide the code. This one http://www.cse.cuhk.edu.hk/leojia/projects/dblurdetect/ is one of the papers that I worked on you can find the code available. You can check also other papers in cvpr. most of them they have the code this is another one http://shijianping.me/jnb/index.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM