{"id":303,"date":"2009-12-04T17:32:57","date_gmt":"2009-12-04T22:32:57","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/2009\/12\/04\/fourier-transform-visualization-using-windowing\/"},"modified":"2019-10-29T08:07:50","modified_gmt":"2019-10-29T12:07:50","slug":"fourier-transform-visualization-using-windowing","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2009\/12\/04\/fourier-transform-visualization-using-windowing\/","title":{"rendered":"Fourier transform visualization using windowing"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <p>When I dipped my toe into the Fourier transform waters <a href=\"https:\/\/blogs.mathworks.com\/steve\/2009\/11\/23\/fourier-transforms\/\">last week<\/a>, the resulting comments and e-mail indicated there is a lot of interest in tutorial material and explanations.  I'm willing,\r\n      but I'll have to think about how to do it.  I haven't taught that material since my professor days, and that was many, many\r\n      moons ago.\r\n   <\/p>\r\n   <p>But I can certainly start by following up on the teaser example from last week.  A reader of <i>Digital Image Processing Using MATLAB<\/i> wanted to know why the Fourier transform of the image below looked so \"funny.\" (For the moment I'm going to use the term\r\n      <i>Fourier transform<\/i> fairly loosely as many people do.)\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">url = <span style=\"color: #A020F0\">'https:\/\/blogs.mathworks.com\/images\/steve\/2009\/lines.png'<\/span>;\r\nf = imread(url);\r\nimshow(f)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2009\/windowing_fft_2_01.jpg\"> <p>I didn't show what the Fourier transform looked like, though, so I suppose it wasn't very clear what problem I was talking\r\n      about.\r\n   <\/p>\r\n   <p>The book recommends this procedure for visualizing the Fourier transform of an image:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">F = fft2(f);\r\nimshow(log(abs(fftshift(F)) + 1), [])<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2009\/windowing_fft_2_02.jpg\"> <p>The puzzle is why does the Fourier transform look so complicated?  The input image, after all, contains only a simple sinusoidal\r\n      pattern.\r\n   <\/p>\r\n   <p>The answer is related to the fact that what we're actually computing when we call <tt>fft2<\/tt> is the two-dimensional <i>discrete Fourier transform<\/i> (DFT). The DFT has an implicit periodicity in both the spatial and the frequency domains.  We don't often don't think about\r\n      the periodicity in either domain, both because we only need one period for computation and because only one period is usually\r\n      shown.\r\n   <\/p>\r\n   <p>Let's see what happens when you take the original image and replicate it a few times.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">I4 = repmat(I, 2, 2);\r\nimshow(I4)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2009\/windowing_fft_2_03.jpg\"> <p>Suddenly the simple sinusoidal pattern doesn't look quite so simple.  What you get here (besides eye strain from looking at\r\n      this image) is a pattern of small vertical and horizontal discontinuities.  These discontinuities are producing the rectangular\r\n      pattern in the frequency-domain visualization above.  That's because any kind of discontinuity has frequency-domain energy\r\n      across a broad range of frequencies.\r\n   <\/p>\r\n   <p>I see this kind of thing in Fourier transform plots all the time, although often the effect is more subtle.  Here's another\r\n      example.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">g = imread(<span style=\"color: #A020F0\">'rice.png'<\/span>);\r\nimshow(g)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2009\/windowing_fft_2_04.jpg\"> <pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">G = fft2(g);\r\nimshow(log(abs(fftshift(G)) + 1), [])<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2009\/windowing_fft_2_05.jpg\"> <p>What's that vertical line in the frequency domain?  There are no horizontal features in the image to account for it.  At least,\r\n      no horizontal features are apparent until you display the periodically replicated image.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">imshow(repmat(g, 2, 2))<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2009\/windowing_fft_2_06.jpg\"> <p>Since the original image is darker at the bottom than at the top, there is a strong horizontal discontinuity at the periodic\r\n      boundary.  That's what causes the vertical line to appear in the frequency domain.\r\n   <\/p>\r\n   <p>One way to remove these frequency-domain effects is to taper the original image values toward 0 at the image boundaries. \r\n      That removes the periodic discontinuities.  The tapering can be done by elementwise multiplication of the original image by\r\n      a matrix equal to 1 in the center and trending toward 0 at the edges.  This is called <i>windowing<\/i>.\r\n   <\/p>\r\n   <p>Let's try that here using a raised cosine function.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">[M, N] = size(f);\r\nw1 = cos(linspace(-pi\/2, pi\/2, M));\r\nw2 = cos(linspace(-pi\/2, pi\/2, N));\r\nw = w1' * w2;\r\nf2 = im2uint8(im2single(f) .* w);\r\nimshow(f2)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2009\/windowing_fft_2_07.jpg\"> <pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">F2 = fft2(f2);\r\nimshow(log(abs(fftshift(F2)) + 1), [])<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2009\/windowing_fft_2_08.jpg\"> <p>Although there are still some visible artifacts, this frequency-domain plot is much closer to showing what we might have expected:\r\n      the Fourier transform of a simple sinusoidal pattern.\r\n   <\/p>\r\n   <p>Here's the same procedure applied to the rice image.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">[M, N] = size(g);\r\nw1 = cos(linspace(-pi\/2, pi\/2, M));\r\nw2 = cos(linspace(-pi\/2, pi\/2, N));\r\nw = w1' * w2;\r\ng2 = im2uint8(im2single(g) .* w);\r\nimshow(g2)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2009\/windowing_fft_2_09.jpg\"> <pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">G2 = fft2(g2);\r\nimshow(log(abs(fftshift(G2)) + 1), [])<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2009\/windowing_fft_2_10.jpg\"> <p>That vertical line in the previous frequency-domain plot is no longer visible.<\/p>\r\n   <p>Since people seem definitely interested in understanding Fourier transforms better, I'll work on putting together more material\r\n      for the blog.  You can help me by continuing to post your comments, including the things that puzzle you.\r\n   <\/p><script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_2fe5476b74f24f808d4524339bc5ab16() {\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='2fe5476b74f24f808d4524339bc5ab16 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 2fe5476b74f24f808d4524339bc5ab16';\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        author = '';\r\n        copyright = 'Copyright 2009 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 author and copyright lines at the bottom if specified.\r\n        if ((author.length > 0) || (copyright.length > 0)) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (author.length > 0) {\r\n                d.writeln('% _' + author + '_');\r\n            }\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      \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_2fe5476b74f24f808d4524339bc5ab16()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n            the MATLAB code \r\n            <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; 7.9<br><\/p>\r\n<\/div>\r\n<!--\r\n2fe5476b74f24f808d4524339bc5ab16 ##### SOURCE BEGIN #####\r\n%%\r\n% When I dipped my toe into the Fourier transform waters \r\n% <https:\/\/blogs.mathworks.com\/steve\/2009\/11\/23\/fourier-transforms\/ last week>, the\r\n% resulting comments and e-mail indicated there is a lot of interest in tutorial\r\n% material and explanations.  I'm willing, but I'll have to think about how to\r\n% do it.  I haven't taught that material since my professor days, and that was\r\n% many, many moons ago.\r\n%\r\n% But I can certainly start by following up on the teaser example from last\r\n% week.  A reader of _Digital Image Processing Using MATLAB_ wanted to know why\r\n% the Fourier transform of the image below looked so \"funny.\" (For the moment\r\n% I'm going to use the term _Fourier transform_ fairly loosely as many people\r\n% do.)\r\n\r\nurl = 'https:\/\/blogs.mathworks.com\/images\/steve\/2009\/lines.png';\r\nf = imread(url);\r\nimshow(f)\r\n\r\n%%\r\n% I didn't show what the Fourier transform looked like, though, so I suppose it\r\n% wasn't very clear what problem I was talking about.\r\n%\r\n% The book recommends this procedure for visualizing the Fourier transform of an\r\n% image:\r\n\r\nF = fft2(f);\r\nimshow(log(abs(fftshift(F)) + 1), [])\r\n\r\n%%\r\n% The puzzle is why does the Fourier transform look so complicated?  The input\r\n% image, after all, contains only a simple sinusoidal pattern.\r\n%\r\n% The answer is related to the fact that what we're actually computing when we\r\n% call |fft2| is the two-dimensional _discrete Fourier transform_ (DFT).\r\n% The DFT has an implicit periodicity in both the spatial and the frequency\r\n% domains.  We don't often don't think about the periodicity in either domain,\r\n% both because we only need one period for computation and because only one\r\n% period is usually shown.\r\n%\r\n% Let's see what happens when you take the original image and replicate it a few\r\n% times.\r\n\r\nI4 = repmat(I, 2, 2);\r\nimshow(I4)\r\n\r\n%%\r\n% Suddenly the simple sinusoidal pattern doesn't look quite so simple.  What you\r\n% get here (besides eye strain from looking at this image) is a pattern of small\r\n% vertical and horizontal discontinuities.  These discontinuities are producing\r\n% the rectangular pattern in the frequency-domain visualization above.  That's\r\n% because any kind of discontinuity has frequency-domain energy across a broad\r\n% range of frequencies.  \r\n%\r\n% I see this kind of thing in Fourier transform plots all the time, although\r\n% often the effect is more subtle.  Here's another example.\r\n\r\ng = imread('rice.png');\r\nimshow(g)\r\n\r\n%%\r\nG = fft2(g);\r\nimshow(log(abs(fftshift(G)) + 1), [])\r\n\r\n%%\r\n% What's that vertical line in the frequency domain?  There are no horizontal\r\n% features in the image to account for it.  At least, no horizontal features are\r\n% apparent until you display the periodically replicated image.\r\n\r\nimshow(repmat(g, 2, 2))\r\n\r\n%%\r\n% Since the original image is darker at the bottom than at the top, there is a\r\n% strong horizontal discontinuity at the periodic boundary.  That's what causes\r\n% the vertical line to appear in the frequency domain.\r\n%\r\n% One way to remove these frequency-domain effects is to taper the original\r\n% image values toward 0 at the image boundaries.  That removes the periodic\r\n% discontinuities.  The tapering can be done by elementwise multiplication of\r\n% the original image by a matrix equal to 1 in the center and trending toward 0\r\n% at the edges.  This is called _windowing_.\r\n%\r\n% Lets try that here using a raised cosine function.\r\n\r\n[M, N] = size(f);\r\nw1 = cos(linspace(-pi\/2, pi\/2, M));\r\nw2 = cos(linspace(-pi\/2, pi\/2, N));\r\nw = w1' * w2;\r\nf2 = im2uint8(im2single(f) .* w);\r\nimshow(f2)\r\n\r\n%%\r\nF2 = fft2(f2);\r\nimshow(log(abs(fftshift(F2)) + 1), [])\r\n\r\n%%\r\n% Although there are still some visible artifacts, this frequency-domain plot is\r\n% much closer to showing what we might have expected: the Fourier transform of a\r\n% simple sinusoidal pattern.\r\n%\r\n% Here's the same procedure applied to the rice image.\r\n\r\n[M, N] = size(g);\r\nw1 = cos(linspace(-pi\/2, pi\/2, M));\r\nw2 = cos(linspace(-pi\/2, pi\/2, N));\r\nw = w1' * w2;\r\ng2 = im2uint8(im2single(g) .* w);\r\nimshow(g2)\r\n\r\n%%\r\nG2 = fft2(g2);\r\nimshow(log(abs(fftshift(G2)) + 1), [])\r\n\r\n%%\r\n% That vertical line in the previous frequency-domain plot is no longer visible.\r\n\r\n%%\r\n% Since people seem definitely interested in understanding Fourier transforms\r\n% better, I'll work on putting together more material for the blog.  You can\r\n% help me by continuing to post your comments, including the things that puzzle\r\n% you.\r\n\r\n##### SOURCE END ##### 2fe5476b74f24f808d4524339bc5ab16\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   When I dipped my toe into the Fourier transform waters last week, the resulting comments and e-mail indicated there is a lot of interest in tutorial material and explanations.  I'm willing,\r\n   ... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2009\/12\/04\/fourier-transform-visualization-using-windowing\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[20],"tags":[208,74,392,400,452,76,36,32,224,532,116,190],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/303"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/comments?post=303"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/303\/revisions"}],"predecessor-version":[{"id":3663,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/303\/revisions\/3663"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=303"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=303"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=303"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}