# How Noisy Are Your Images?

Brett's Picks this week are: Image Blur Metric, by Do Quoc Bao; Blind image quality assessment through anisotropy, by Salvador Gabarda; and Noise Level Estimation from a Single Image, by Masayuki Tanaka.

Brett returns to his roots as an image processing geek this week to pose a question that he gets asked by customers from time to time. Namely, 'How can I quantify the noise in my image?'

In R2014a, we added two functions that facilitate the measurement of image noise: ssim, with which you can calculate the overall or pixelwise "structural similarity index"; and psnr, for computing the signal-to-noise ratio (peak or simple) of an image.

Both of these calculations are made by comparing a potentially noisy image to a "pristine" one; if you have a reference image and you need to calculate deviations from it, these functions may serve you well. (Note that there are many other files on the the File Exchange that facilitate different reference-image quality metrics. Do a quick search for "image quality"; you'll find several.)

But what if you don't have a reference image to which to compare your noisy image? That is, what if you need to do a "blind" image quality assessment? This can be simultaneously much more useful and much more difficult. Approaches to blind noise assessment often focus on quantification of blur or, conversely, determination of edge sharpness. I have on numerous occasions successfully used the "threshold" output of the various edge metrics to decide which images are of higher quality. For instance:

ax = zeros(3,1);
% Pristine
ax(1) = subplot(1,3,1);
[~,thresh] = edge(img,'sobel');
imshow(img)
title(sprintf('Edge threshold = %0.2f',thresh))
% Some noise
h = fspecial('motion', 5, 0);
img2 = imfilter(img,h,'replicate');
ax(2) = subplot(1,3,2);
[~,thresh] = edge(img2,'sobel');
imshow(img2);
title(sprintf('Edge threshold = %0.2f',thresh))
% More noise
h = fspecial('motion', 15, 0);
img3 = imfilter(img,h,'replicate');
ax(3) = subplot(1,3,3);
[~,thresh] = edge(img3,'sobel');
imshow(img3)
title(sprintf('Edge threshold = %0.2f',thresh))


Todays Picks facilitate blind image quality assessment. The first is Do Quoc Bao's Image Blur Metric. While the code could use some commenting and error checking, it is well implemented; it cites the SPIE Procedings from which it was taken; and it is exceedingly easy to use; simply, the blur metric is reported to range from 0 to 1, with 0 indicating "sharp," and 1 representing "blurry":

title(ax(1),sprintf('Blur = %0.2f',blurMetric(img)))
title(ax(2),sprintf('Blur = %0.2f',blurMetric(img2)))
title(ax(3),sprintf('Blur = %0.2f',blurMetric(img3)))


Next, check out Blind image quality assessment through anisotropy, by Salvador Gabarda. Salvador's blind analysis "discriminates blur and Gaussian noise...given a set of registered images, the image showing the highest index is the best. It works on grayscale or color images, and provides lots of parameters to play with.

title(ax(1),sprintf('1000*Quality = %0.2f',1000*blindimagequality(img,2)))
title(ax(2),sprintf('1000*Quality = %0.2f',1000*blindimagequality(img2,2)))
title(ax(3),sprintf('1000*Quality = %0.2f',1000*blindimagequality(img3,2)))


Finally, consider Noise Level Estimation from a Single Image, by Masayuki Tanaka. I haven't read Masayuki's original paper on the topic; perhaps it explains why the output value appears to change inversely with blur. (Masayuki, care to chime in on that?) This implementation also works on grayscale or color images, though analysis is plane-by-plane for the latter case. Also, I'm not sure why the output value appears to change inversely with blur:

title(ax(1),sprintf('1000*Noise Estimate = %0.2f',1000*NLEstimate(img)))
title(ax(2),sprintf('1000*Noise Estimate = %0.2f',1000*NLEstimate(img2)))
title(ax(3),sprintf('1000*Noise Estimate = %0.2f',1000*NLEstimate(img3)))


What use cases do you have for estimating noise in images? Are you more likely to need "blind" approaches, or do methods that compare to a reference image typically suffice? I'd love to hear from you!