{"id":5499,"date":"2014-09-05T09:00:42","date_gmt":"2014-09-05T13:00:42","guid":{"rendered":"https:\/\/blogs.mathworks.com\/pick\/?p=5499"},"modified":"2014-09-03T09:35:33","modified_gmt":"2014-09-03T13:35:33","slug":"how-noisy-are-your-images","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/pick\/2014\/09\/05\/how-noisy-are-your-images\/","title":{"rendered":"How Noisy Are Your Images?"},"content":{"rendered":"\r\n<div class=\"content\"><!--introduction--><!--\/introduction--><p><a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/911\">Brett<\/a>'s Picks this week are: <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/24676-image-blur-metric\">Image Blur Metric<\/a>, by <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/63035\">Do Quoc Bao<\/a>; <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/30800-blind-image-quality-assessment-through-anisotropy\">Blind image quality assessment through anisotropy<\/a>, by <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/127745\">Salvador Gabarda<\/a>; and <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/36921-noise-level-estimation-from-a-single-image\">Noise Level Estimation from a Single Image<\/a>, by <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/253277\">Masayuki Tanaka<\/a>.<\/p><p>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, <i>'How can I quantify the noise in my image?'<\/i><\/p><p>In R2014a, we added two functions that facilitate the measurement of image noise: <a href=\"https:\/\/www.mathworks.com\/help\/images\/ref\/ssim.html\"><tt>ssim<\/tt><\/a>, with which you can calculate the overall or pixelwise \"structural similarity index\"; and <a href=\"https:\/\/www.mathworks.com\/help\/images\/ref\/psnr.html\"><tt>psnr<\/tt><\/a>, for computing the signal-to-noise ratio (peak or simple) of an image.<\/p><p>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.)<\/p><p>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 <tt>edge<\/tt> metrics to decide which images are of higher quality. For instance:<\/p><pre class=\"language-matlab\">ax = zeros(3,1);\r\n<span class=\"comment\">% Pristine<\/span>\r\nimg = imread(<span class=\"string\">'rice.png'<\/span>);\r\nax(1) = subplot(1,3,1);\r\n[~,thresh] = edge(img,<span class=\"string\">'sobel'<\/span>);\r\nimshow(img)\r\ntitle(sprintf(<span class=\"string\">'Edge threshold = %0.2f'<\/span>,thresh))\r\n<span class=\"comment\">% Some noise<\/span>\r\nh = fspecial(<span class=\"string\">'motion'<\/span>, 5, 0);\r\nimg2 = imfilter(img,h,<span class=\"string\">'replicate'<\/span>);\r\nax(2) = subplot(1,3,2);\r\n[~,thresh] = edge(img2,<span class=\"string\">'sobel'<\/span>);\r\nimshow(img2);\r\ntitle(sprintf(<span class=\"string\">'Edge threshold = %0.2f'<\/span>,thresh))\r\n<span class=\"comment\">% More noise<\/span>\r\nh = fspecial(<span class=\"string\">'motion'<\/span>, 15, 0);\r\nimg3 = imfilter(img,h,<span class=\"string\">'replicate'<\/span>);\r\nax(3) = subplot(1,3,3);\r\n[~,thresh] = edge(img3,<span class=\"string\">'sobel'<\/span>);\r\nimshow(img3)\r\ntitle(sprintf(<span class=\"string\">'Edge threshold = %0.2f'<\/span>,thresh))\r\n<\/pre><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/pick\/files\/edgeThresholdImage.png\" alt=\"\"> <\/p><p>Todays Picks facilitate blind image quality assessment. The first is <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/63035\">Do Quoc Bao<\/a>'s <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/24676-image-blur-metric\">Image Blur Metric<\/a>. 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\":<\/p><pre class=\"language-matlab\">title(ax(1),sprintf(<span class=\"string\">'Blur = %0.2f'<\/span>,blurMetric(img)))\r\ntitle(ax(2),sprintf(<span class=\"string\">'Blur = %0.2f'<\/span>,blurMetric(img2)))\r\ntitle(ax(3),sprintf(<span class=\"string\">'Blur = %0.2f'<\/span>,blurMetric(img3)))\r\n<\/pre><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/pick\/files\/blurValueImage.png\" alt=\"\"> <\/p><p>Next, check out <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/30800-blind-image-quality-assessment-through-anisotropy\">Blind image quality assessment through anisotropy<\/a>, by <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/127745\">Salvador Gabarda<\/a>. 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.<\/p><pre class=\"language-matlab\">title(ax(1),sprintf(<span class=\"string\">'1000*Quality = %0.2f'<\/span>,1000*blindimagequality(img,2)))\r\ntitle(ax(2),sprintf(<span class=\"string\">'1000*Quality = %0.2f'<\/span>,1000*blindimagequality(img2,2)))\r\ntitle(ax(3),sprintf(<span class=\"string\">'1000*Quality = %0.2f'<\/span>,1000*blindimagequality(img3,2)))\r\n<\/pre><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/pick\/files\/blindImageQualityImage.png\" alt=\"\"> <\/p><p>Finally, consider <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/36921-noise-level-estimation-from-a-single-image\">Noise Level Estimation from a Single Image<\/a>, by <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/253277\">Masayuki Tanaka<\/a>. 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:<\/p><pre class=\"language-matlab\">title(ax(1),sprintf(<span class=\"string\">'1000*Noise Estimate = %0.2f'<\/span>,1000*NLEstimate(img)))\r\ntitle(ax(2),sprintf(<span class=\"string\">'1000*Noise Estimate = %0.2f'<\/span>,1000*NLEstimate(img2)))\r\ntitle(ax(3),sprintf(<span class=\"string\">'1000*Noise Estimate = %0.2f'<\/span>,1000*NLEstimate(img3)))\r\n<\/pre><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/pick\/files\/NLEstImage.png\" alt=\"\"> <\/p><p>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!<\/p><p>As always, I welcome your <a href=\"https:\/\/blogs.mathworks.com\/pick\/?p=5499#respond\">thoughts and comments<\/a>.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_35b544e292d54ea8a99a9b9464dc19b5() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='35b544e292d54ea8a99a9b9464dc19b5 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 35b544e292d54ea8a99a9b9464dc19b5';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2014 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_35b544e292d54ea8a99a9b9464dc19b5()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2014a<br><\/p><\/div><!--\r\n35b544e292d54ea8a99a9b9464dc19b5 ##### SOURCE BEGIN #####\r\n%% How noisy is your image?\r\n%% \r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/911 Brett>'s Picks this week\r\n% are: <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/24676-image-blur-metric Image Blur Metric>, \r\n% by <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/63035 Do Quoc Bao>; \r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/30800-blind-image-quality-assessment-through-anisotropy Blind image quality assessment through anisotropy>, by \r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/127745 Salvador Gabarda>; and \r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/36921-noise-level-estimation-from-a-single-image Noise Level Estimation from a Single Image>, by\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/253277 Masayuki Tanaka>. \r\n\r\n%%\r\n% Brett returns to his roots as an image processing geek this week to pose a question that\r\n% he gets asked by customers from time to time. Namely, _'How can I quantify\r\n% the noise in my image?'_ \r\n\r\n%% \r\n% In R2014a, we added two functions that facilitate the measurement of\r\n% image noise:\r\n% <https:\/\/www.mathworks.com\/help\/images\/ref\/ssim.html |ssim|>, \r\n% with which you can calculate the overall or pixelwise \"structural similarity index\"; and \r\n% <https:\/\/www.mathworks.com\/help\/images\/ref\/psnr.html |psnr|>, \r\n% for computing the signal-to-noise ratio (peak or simple) of an image.\r\n\r\n%%\r\n% Both of these calculations are made by comparing a potentially noisy\r\n% image to a \"pristine\" one; if you have a reference image and you need to\r\n% calculate deviations from it, these functions may serve you well. (Note\r\n% that there are many other files on the the File Exchange that\r\n% facilitate different reference-image quality metrics. Do a quick search\r\n% for \"image quality\"; you'll find several.) \r\n\r\n%% \r\n% But what if you don't have a reference image to which to compare your\r\n% noisy image? That is, what if you need to do a \"blind\" image quality\r\n% assessment?  This can be simultaneously much more useful and much more\r\n% difficult. Approaches to blind noise assessment often focus on\r\n% quantification of blur or, conversely, determination of edge sharpness. I\r\n% have on numerous occasions successfully used the \"threshold\" output of the \r\n% various |edge|\r\n% metrics to decide which images are of higher quality. For instance:\r\n\r\n%%\r\n%   ax = zeros(3,1);\r\n%   % Pristine\r\n%   img = imread('rice.png');\r\n%   ax(1) = subplot(1,3,1);\r\n%   [~,thresh] = edge(img,'sobel');\r\n%   imshow(img)\r\n%   title(sprintf('Edge threshold = %0.2f',thresh))\r\n%   % Some noise\r\n%   h = fspecial('motion', 5, 0);\r\n%   img2 = imfilter(img,h,'replicate');\r\n%   ax(2) = subplot(1,3,2);\r\n%   [~,thresh] = edge(img2,'sobel');\r\n%   imshow(img2);\r\n%   title(sprintf('Edge threshold = %0.2f',thresh))\r\n%   % More noise \r\n%   h = fspecial('motion', 15, 0);\r\n%   img3 = imfilter(img,h,'replicate');\r\n%   ax(3) = subplot(1,3,3);\r\n%   [~,thresh] = edge(img3,'sobel');\r\n%   imshow(img3)\r\n%   title(sprintf('Edge threshold = %0.2f',thresh))\r\n\r\n%%\r\n% \r\n% <<https:\/\/blogs.mathworks.com\/pick\/files\/edgeThresholdImage.png>>\r\n% \r\n\r\n%% \r\n% Todays Picks facilitate blind image quality assessment. The first is \r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/63035 Do Quoc Bao>'s\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/24676-image-blur-metric Image Blur Metric>. \r\n% While the code could use some commenting and error checking, it is well\r\n% implemented; it cites the SPIE Procedings from which it was taken; and it\r\n% is exceedingly easy to use; simply, the blur metric is reported to range \r\n% from 0 to 1, with 0 indicating \"sharp,\" and 1 representing \"blurry\":\r\n\r\n%%\r\n%   title(ax(1),sprintf('Blur = %0.2f',blurMetric(img)))\r\n%   title(ax(2),sprintf('Blur = %0.2f',blurMetric(img2)))\r\n%   title(ax(3),sprintf('Blur = %0.2f',blurMetric(img3)))\r\n\r\n%%\r\n% \r\n% <<https:\/\/blogs.mathworks.com\/pick\/files\/blurValueImage.png>>\r\n% \r\n\r\n%%\r\n% Next, check out \r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/30800-blind-image-quality-assessment-through-anisotropy Blind image quality assessment through anisotropy>, by \r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/127745 Salvador Gabarda>. \r\n% Salvador's blind analysis \"discriminates blur and Gaussian noise...given a set of \r\n% registered images, the image showing the highest index is the best. It\r\n% works on grayscale or color images, and provides lots of parameters to\r\n% play with.\r\n\r\n%%\r\n%   title(ax(1),sprintf('1000*Quality = %0.2f',1000*blindimagequality(img,2)))\r\n%   title(ax(2),sprintf('1000*Quality = %0.2f',1000*blindimagequality(img2,2)))\r\n%   title(ax(3),sprintf('1000*Quality = %0.2f',1000*blindimagequality(img3,2)))\r\n%%\r\n% \r\n% <<https:\/\/blogs.mathworks.com\/pick\/files\/blindImageQualityImage.png>>\r\n% \r\n%%\r\n% Finally, consider\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/36921-noise-level-estimation-from-a-single-image Noise Level Estimation from a Single Image>, by\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/253277 Masayuki Tanaka>.\r\n% I haven't read Masayuki's original paper on the topic;\r\n% perhaps it explains why the output value appears to change inversely with\r\n% blur. (Masayuki, care to chime in on that?) This implementation also\r\n% works on grayscale or color images, though analysis is plane-by-plane for\r\n% the latter case. Also, I'm not sure why the output value appears to\r\n% change inversely with blur:\r\n\r\n%%\r\n%   title(ax(1),sprintf('1000*Noise Estimate = %0.2f',1000*NLEstimate(img)))\r\n%   title(ax(2),sprintf('1000*Noise Estimate = %0.2f',1000*NLEstimate(img2)))\r\n%   title(ax(3),sprintf('1000*Noise Estimate = %0.2f',1000*NLEstimate(img3)))\r\n%%\r\n% \r\n% <<https:\/\/blogs.mathworks.com\/pick\/files\/NLEstImage.png>>\r\n% \r\n%%\r\n% What use cases do you have for estimating noise in images? Are you more\r\n% likely to need \"blind\" approaches, or do methods that compare to a\r\n% reference image typically suffice? I'd love to hear from you!\r\n%%\r\n% As always, I welcome your\r\n% <https:\/\/blogs.mathworks.com\/pick\/?p=5499#respond thoughts and comments>.\r\n##### SOURCE END ##### 35b544e292d54ea8a99a9b9464dc19b5\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/pick\/files\/edgeThresholdImage.png\" onError=\"this.style.display ='none';\" \/><\/div><p>\r\nBrett'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... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/pick\/2014\/09\/05\/how-noisy-are-your-images\/\">read more >><\/a><\/p>","protected":false},"author":34,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[16],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts\/5499"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/users\/34"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/comments?post=5499"}],"version-history":[{"count":16,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts\/5499\/revisions"}],"predecessor-version":[{"id":5522,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts\/5499\/revisions\/5522"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/media?parent=5499"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/categories?post=5499"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/tags?post=5499"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}