Why using magnitude method to get processed image?
Hi guys I’ve thinking about this question:
I know that we use Fourier transform to get into frequency domain to process the image.
I read the text book, it said that when we are done with processing the image in the Fourier domain we have to invert it back to get processed image.
And the textbook taught to get the real part of the inverse.
However, when I go through the OpenCv tutorial, no matter if using OpenCV or NumPy version, eventually they use magnitude
(for OpenCV) or np.abs
(for NumPy).
For OpenCV, the inverse returns two channels which contain the real and imaginary components. When I took the real part of the inverse, I got a totally weird image.
May somebody who knows the meaning behind all of this:
Why using
magnitude
orabs
to get processed image?What’s wrong with textbook instruction (take the real part of inverse)?
opencv image-processing fft magnitude
add a comment |
Hi guys I’ve thinking about this question:
I know that we use Fourier transform to get into frequency domain to process the image.
I read the text book, it said that when we are done with processing the image in the Fourier domain we have to invert it back to get processed image.
And the textbook taught to get the real part of the inverse.
However, when I go through the OpenCv tutorial, no matter if using OpenCV or NumPy version, eventually they use magnitude
(for OpenCV) or np.abs
(for NumPy).
For OpenCV, the inverse returns two channels which contain the real and imaginary components. When I took the real part of the inverse, I got a totally weird image.
May somebody who knows the meaning behind all of this:
Why using
magnitude
orabs
to get processed image?What’s wrong with textbook instruction (take the real part of inverse)?
opencv image-processing fft magnitude
you can only use real numbers in image, when you take inverse fourier transform it might have complex numbers as output, so you need to get real part of the inverse FT and display it as an image
– user8190410
Nov 12 '18 at 17:19
docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/….
– kris
Nov 12 '18 at 17:27
The link calculate the magnitude and the result looks great
– kris
Nov 12 '18 at 17:27
add a comment |
Hi guys I’ve thinking about this question:
I know that we use Fourier transform to get into frequency domain to process the image.
I read the text book, it said that when we are done with processing the image in the Fourier domain we have to invert it back to get processed image.
And the textbook taught to get the real part of the inverse.
However, when I go through the OpenCv tutorial, no matter if using OpenCV or NumPy version, eventually they use magnitude
(for OpenCV) or np.abs
(for NumPy).
For OpenCV, the inverse returns two channels which contain the real and imaginary components. When I took the real part of the inverse, I got a totally weird image.
May somebody who knows the meaning behind all of this:
Why using
magnitude
orabs
to get processed image?What’s wrong with textbook instruction (take the real part of inverse)?
opencv image-processing fft magnitude
Hi guys I’ve thinking about this question:
I know that we use Fourier transform to get into frequency domain to process the image.
I read the text book, it said that when we are done with processing the image in the Fourier domain we have to invert it back to get processed image.
And the textbook taught to get the real part of the inverse.
However, when I go through the OpenCv tutorial, no matter if using OpenCV or NumPy version, eventually they use magnitude
(for OpenCV) or np.abs
(for NumPy).
For OpenCV, the inverse returns two channels which contain the real and imaginary components. When I took the real part of the inverse, I got a totally weird image.
May somebody who knows the meaning behind all of this:
Why using
magnitude
orabs
to get processed image?What’s wrong with textbook instruction (take the real part of inverse)?
opencv image-processing fft magnitude
opencv image-processing fft magnitude
edited Nov 12 '18 at 17:43
Cris Luengo
21.3k52250
21.3k52250
asked Nov 12 '18 at 17:08
kriskris
345
345
you can only use real numbers in image, when you take inverse fourier transform it might have complex numbers as output, so you need to get real part of the inverse FT and display it as an image
– user8190410
Nov 12 '18 at 17:19
docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/….
– kris
Nov 12 '18 at 17:27
The link calculate the magnitude and the result looks great
– kris
Nov 12 '18 at 17:27
add a comment |
you can only use real numbers in image, when you take inverse fourier transform it might have complex numbers as output, so you need to get real part of the inverse FT and display it as an image
– user8190410
Nov 12 '18 at 17:19
docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/….
– kris
Nov 12 '18 at 17:27
The link calculate the magnitude and the result looks great
– kris
Nov 12 '18 at 17:27
you can only use real numbers in image, when you take inverse fourier transform it might have complex numbers as output, so you need to get real part of the inverse FT and display it as an image
– user8190410
Nov 12 '18 at 17:19
you can only use real numbers in image, when you take inverse fourier transform it might have complex numbers as output, so you need to get real part of the inverse FT and display it as an image
– user8190410
Nov 12 '18 at 17:19
docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/….
– kris
Nov 12 '18 at 17:27
docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/….
– kris
Nov 12 '18 at 17:27
The link calculate the magnitude and the result looks great
– kris
Nov 12 '18 at 17:27
The link calculate the magnitude and the result looks great
– kris
Nov 12 '18 at 17:27
add a comment |
1 Answer
1
active
oldest
votes
The textbook is right, the tutorial is wrong.
A real-valued image has a complex conjugate symmetry in the Fourier domain. This means that the FFT of the image will have a specific symmetry. Any processing that you do must preserve this symmetry if you want the inverse transform to remain real-valued. If you do this processing wrong, then the inverse transform will be complex-valued, and probably non-sensical.
If you preserve the symmetry in the Fourier domain properly, then the imaginary component of the inverse transform will be nearly zero (likely different from zero because of numerical imprecision). Discarding this imaginary component is the correct thing to do. Computing the magnitude will yield the same result, except all negative values will become positive (note some filters are meant to produce negative values, such as derivative filters), and at an increased computational cost.
For example, a convolution is a multiplication in the Fourier domain. The filter in the Fourier domain must be real-valued and symmetric around the origin. Often people will confuse where the origin is in the Fourier domain, and multiply by a filter that is seems symmetric, but actually is shifted with respect to the origin making it not symmetric. This shift introduces a phase change of the inverse transform (see the shift property of the Fourier transform). The magnitude of the inverse transform is not affected by the phase change, so taking the magnitude of this inverse transform yields an output that sort of looks OK, except if one expects to see negative values in the filter result. It would have been better to correctly understand the FFT algorithm, create a properly symmetric filter in the Fourier domain, and simply keep the real part of the inverse transform.
Nonetheless, some filters are specifically designed to break the symmetry and yield a complex-valued filter output. For example the Gabor filter has an even (symmetric) component and an odd (anti-symmetric) component. The even component yields a real-valued output, the odd component yields an imaginary-valued output. In this case, it is the magnitude of the complex value that is of interest. Likewise, a quadrature filter is specifically meant to produce a complex-valued output. From this output, the analytic signal (or its multi-dimensional extension, the monogenic signal), both the magnitude and the phase are of interest, for example as used in the phase congruency method of edge detection.
Looking at the linked tutorial, it is the line
fshift[crow-30:crow+30, ccol-30:ccol+30] = 0
which generates the Fourier-domain filter and applies it to the image (it is equivalent to multiplying by a filter with 1s and 0s). This tutorial correctly computes the origin of the Fourier domain (though for Python 3 you would use crow,ccol = rows//2 , cols//2
to get the integer division). But the filter above is not symmetric around that origin. In Python, crow-30:crow+30
indicates 30 pixels to the left of the origin, and only 29 pixels to the right (the right bound is not included!). The correct filter would be:
fshift[crow-30:crow+30+1, ccol-30:ccol+30+1] = 0
With this filter, the inverse transform is purely real (imaginary component has values in the order of 1e-13
, which is numerical errors). Thus, it is now possible (and correct) to replace img_back = np.abs(img_back)
with img_back = np.real(img_back)
.
1
@kris: it depends on how you created the kernel. In the tutorial, they usedfftshift
on the transform, which means that the origin is in the middle of the image. Your kernel must be designed to have the origin in the same location. If your kernel is the result of an FFT of a kernel made in the spatial domain, you should applyifftshift
to the spatial-domain kernel, then applyfft
to the image and the shifted kernel, then multiply, then do the inverse transform (nofftshift
in the Fourier domain).
– Cris Luengo
Nov 12 '18 at 17:59
1
@kris: If the filter is not symmetric, then the inverse transform will be a complex-valued function. Some filters are designed this way (see the paragraph I added to the answer). It depends on the filter and how it is designed, what one does with the complex output. The discussion about symmetric filters relates to filters that are meant to keep the real-valued image being real-valued, such as low-pass, high-pass or band-pass filters.
– Cris Luengo
Nov 13 '18 at 5:19
1
The error in the OpenCV documentation has been corrected: github.com/opencv/opencv/issues/13152
– Cris Luengo
Nov 16 '18 at 2:52
1
@kris: the FT is a continuous-domain construct that requires an infinitely long signal. Sampling this signal leads to a periodic frequency domain. Now you have the DTFT (discrete time FT). Windowing the signal (when we measure a signal we don’t have infinitely long data) means we cannot apply the FT any more. So instead we assume periodicity of the signal, repeating it infinitely. Now we do have something we can compute the FT of. The periodicity leads to a discrete frequency domain. Now you have a DFT (discrete FT). The FFT computes the DFT.
– Cris Luengo
Nov 29 '18 at 14:17
1
@kris: The DSP Stack Exchange is a good place to ask questions about Fourier analysis and many other things.
– Cris Luengo
Nov 30 '18 at 6:26
|
show 12 more comments
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53266944%2fwhy-using-magnitude-method-to-get-processed-image%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The textbook is right, the tutorial is wrong.
A real-valued image has a complex conjugate symmetry in the Fourier domain. This means that the FFT of the image will have a specific symmetry. Any processing that you do must preserve this symmetry if you want the inverse transform to remain real-valued. If you do this processing wrong, then the inverse transform will be complex-valued, and probably non-sensical.
If you preserve the symmetry in the Fourier domain properly, then the imaginary component of the inverse transform will be nearly zero (likely different from zero because of numerical imprecision). Discarding this imaginary component is the correct thing to do. Computing the magnitude will yield the same result, except all negative values will become positive (note some filters are meant to produce negative values, such as derivative filters), and at an increased computational cost.
For example, a convolution is a multiplication in the Fourier domain. The filter in the Fourier domain must be real-valued and symmetric around the origin. Often people will confuse where the origin is in the Fourier domain, and multiply by a filter that is seems symmetric, but actually is shifted with respect to the origin making it not symmetric. This shift introduces a phase change of the inverse transform (see the shift property of the Fourier transform). The magnitude of the inverse transform is not affected by the phase change, so taking the magnitude of this inverse transform yields an output that sort of looks OK, except if one expects to see negative values in the filter result. It would have been better to correctly understand the FFT algorithm, create a properly symmetric filter in the Fourier domain, and simply keep the real part of the inverse transform.
Nonetheless, some filters are specifically designed to break the symmetry and yield a complex-valued filter output. For example the Gabor filter has an even (symmetric) component and an odd (anti-symmetric) component. The even component yields a real-valued output, the odd component yields an imaginary-valued output. In this case, it is the magnitude of the complex value that is of interest. Likewise, a quadrature filter is specifically meant to produce a complex-valued output. From this output, the analytic signal (or its multi-dimensional extension, the monogenic signal), both the magnitude and the phase are of interest, for example as used in the phase congruency method of edge detection.
Looking at the linked tutorial, it is the line
fshift[crow-30:crow+30, ccol-30:ccol+30] = 0
which generates the Fourier-domain filter and applies it to the image (it is equivalent to multiplying by a filter with 1s and 0s). This tutorial correctly computes the origin of the Fourier domain (though for Python 3 you would use crow,ccol = rows//2 , cols//2
to get the integer division). But the filter above is not symmetric around that origin. In Python, crow-30:crow+30
indicates 30 pixels to the left of the origin, and only 29 pixels to the right (the right bound is not included!). The correct filter would be:
fshift[crow-30:crow+30+1, ccol-30:ccol+30+1] = 0
With this filter, the inverse transform is purely real (imaginary component has values in the order of 1e-13
, which is numerical errors). Thus, it is now possible (and correct) to replace img_back = np.abs(img_back)
with img_back = np.real(img_back)
.
1
@kris: it depends on how you created the kernel. In the tutorial, they usedfftshift
on the transform, which means that the origin is in the middle of the image. Your kernel must be designed to have the origin in the same location. If your kernel is the result of an FFT of a kernel made in the spatial domain, you should applyifftshift
to the spatial-domain kernel, then applyfft
to the image and the shifted kernel, then multiply, then do the inverse transform (nofftshift
in the Fourier domain).
– Cris Luengo
Nov 12 '18 at 17:59
1
@kris: If the filter is not symmetric, then the inverse transform will be a complex-valued function. Some filters are designed this way (see the paragraph I added to the answer). It depends on the filter and how it is designed, what one does with the complex output. The discussion about symmetric filters relates to filters that are meant to keep the real-valued image being real-valued, such as low-pass, high-pass or band-pass filters.
– Cris Luengo
Nov 13 '18 at 5:19
1
The error in the OpenCV documentation has been corrected: github.com/opencv/opencv/issues/13152
– Cris Luengo
Nov 16 '18 at 2:52
1
@kris: the FT is a continuous-domain construct that requires an infinitely long signal. Sampling this signal leads to a periodic frequency domain. Now you have the DTFT (discrete time FT). Windowing the signal (when we measure a signal we don’t have infinitely long data) means we cannot apply the FT any more. So instead we assume periodicity of the signal, repeating it infinitely. Now we do have something we can compute the FT of. The periodicity leads to a discrete frequency domain. Now you have a DFT (discrete FT). The FFT computes the DFT.
– Cris Luengo
Nov 29 '18 at 14:17
1
@kris: The DSP Stack Exchange is a good place to ask questions about Fourier analysis and many other things.
– Cris Luengo
Nov 30 '18 at 6:26
|
show 12 more comments
The textbook is right, the tutorial is wrong.
A real-valued image has a complex conjugate symmetry in the Fourier domain. This means that the FFT of the image will have a specific symmetry. Any processing that you do must preserve this symmetry if you want the inverse transform to remain real-valued. If you do this processing wrong, then the inverse transform will be complex-valued, and probably non-sensical.
If you preserve the symmetry in the Fourier domain properly, then the imaginary component of the inverse transform will be nearly zero (likely different from zero because of numerical imprecision). Discarding this imaginary component is the correct thing to do. Computing the magnitude will yield the same result, except all negative values will become positive (note some filters are meant to produce negative values, such as derivative filters), and at an increased computational cost.
For example, a convolution is a multiplication in the Fourier domain. The filter in the Fourier domain must be real-valued and symmetric around the origin. Often people will confuse where the origin is in the Fourier domain, and multiply by a filter that is seems symmetric, but actually is shifted with respect to the origin making it not symmetric. This shift introduces a phase change of the inverse transform (see the shift property of the Fourier transform). The magnitude of the inverse transform is not affected by the phase change, so taking the magnitude of this inverse transform yields an output that sort of looks OK, except if one expects to see negative values in the filter result. It would have been better to correctly understand the FFT algorithm, create a properly symmetric filter in the Fourier domain, and simply keep the real part of the inverse transform.
Nonetheless, some filters are specifically designed to break the symmetry and yield a complex-valued filter output. For example the Gabor filter has an even (symmetric) component and an odd (anti-symmetric) component. The even component yields a real-valued output, the odd component yields an imaginary-valued output. In this case, it is the magnitude of the complex value that is of interest. Likewise, a quadrature filter is specifically meant to produce a complex-valued output. From this output, the analytic signal (or its multi-dimensional extension, the monogenic signal), both the magnitude and the phase are of interest, for example as used in the phase congruency method of edge detection.
Looking at the linked tutorial, it is the line
fshift[crow-30:crow+30, ccol-30:ccol+30] = 0
which generates the Fourier-domain filter and applies it to the image (it is equivalent to multiplying by a filter with 1s and 0s). This tutorial correctly computes the origin of the Fourier domain (though for Python 3 you would use crow,ccol = rows//2 , cols//2
to get the integer division). But the filter above is not symmetric around that origin. In Python, crow-30:crow+30
indicates 30 pixels to the left of the origin, and only 29 pixels to the right (the right bound is not included!). The correct filter would be:
fshift[crow-30:crow+30+1, ccol-30:ccol+30+1] = 0
With this filter, the inverse transform is purely real (imaginary component has values in the order of 1e-13
, which is numerical errors). Thus, it is now possible (and correct) to replace img_back = np.abs(img_back)
with img_back = np.real(img_back)
.
1
@kris: it depends on how you created the kernel. In the tutorial, they usedfftshift
on the transform, which means that the origin is in the middle of the image. Your kernel must be designed to have the origin in the same location. If your kernel is the result of an FFT of a kernel made in the spatial domain, you should applyifftshift
to the spatial-domain kernel, then applyfft
to the image and the shifted kernel, then multiply, then do the inverse transform (nofftshift
in the Fourier domain).
– Cris Luengo
Nov 12 '18 at 17:59
1
@kris: If the filter is not symmetric, then the inverse transform will be a complex-valued function. Some filters are designed this way (see the paragraph I added to the answer). It depends on the filter and how it is designed, what one does with the complex output. The discussion about symmetric filters relates to filters that are meant to keep the real-valued image being real-valued, such as low-pass, high-pass or band-pass filters.
– Cris Luengo
Nov 13 '18 at 5:19
1
The error in the OpenCV documentation has been corrected: github.com/opencv/opencv/issues/13152
– Cris Luengo
Nov 16 '18 at 2:52
1
@kris: the FT is a continuous-domain construct that requires an infinitely long signal. Sampling this signal leads to a periodic frequency domain. Now you have the DTFT (discrete time FT). Windowing the signal (when we measure a signal we don’t have infinitely long data) means we cannot apply the FT any more. So instead we assume periodicity of the signal, repeating it infinitely. Now we do have something we can compute the FT of. The periodicity leads to a discrete frequency domain. Now you have a DFT (discrete FT). The FFT computes the DFT.
– Cris Luengo
Nov 29 '18 at 14:17
1
@kris: The DSP Stack Exchange is a good place to ask questions about Fourier analysis and many other things.
– Cris Luengo
Nov 30 '18 at 6:26
|
show 12 more comments
The textbook is right, the tutorial is wrong.
A real-valued image has a complex conjugate symmetry in the Fourier domain. This means that the FFT of the image will have a specific symmetry. Any processing that you do must preserve this symmetry if you want the inverse transform to remain real-valued. If you do this processing wrong, then the inverse transform will be complex-valued, and probably non-sensical.
If you preserve the symmetry in the Fourier domain properly, then the imaginary component of the inverse transform will be nearly zero (likely different from zero because of numerical imprecision). Discarding this imaginary component is the correct thing to do. Computing the magnitude will yield the same result, except all negative values will become positive (note some filters are meant to produce negative values, such as derivative filters), and at an increased computational cost.
For example, a convolution is a multiplication in the Fourier domain. The filter in the Fourier domain must be real-valued and symmetric around the origin. Often people will confuse where the origin is in the Fourier domain, and multiply by a filter that is seems symmetric, but actually is shifted with respect to the origin making it not symmetric. This shift introduces a phase change of the inverse transform (see the shift property of the Fourier transform). The magnitude of the inverse transform is not affected by the phase change, so taking the magnitude of this inverse transform yields an output that sort of looks OK, except if one expects to see negative values in the filter result. It would have been better to correctly understand the FFT algorithm, create a properly symmetric filter in the Fourier domain, and simply keep the real part of the inverse transform.
Nonetheless, some filters are specifically designed to break the symmetry and yield a complex-valued filter output. For example the Gabor filter has an even (symmetric) component and an odd (anti-symmetric) component. The even component yields a real-valued output, the odd component yields an imaginary-valued output. In this case, it is the magnitude of the complex value that is of interest. Likewise, a quadrature filter is specifically meant to produce a complex-valued output. From this output, the analytic signal (or its multi-dimensional extension, the monogenic signal), both the magnitude and the phase are of interest, for example as used in the phase congruency method of edge detection.
Looking at the linked tutorial, it is the line
fshift[crow-30:crow+30, ccol-30:ccol+30] = 0
which generates the Fourier-domain filter and applies it to the image (it is equivalent to multiplying by a filter with 1s and 0s). This tutorial correctly computes the origin of the Fourier domain (though for Python 3 you would use crow,ccol = rows//2 , cols//2
to get the integer division). But the filter above is not symmetric around that origin. In Python, crow-30:crow+30
indicates 30 pixels to the left of the origin, and only 29 pixels to the right (the right bound is not included!). The correct filter would be:
fshift[crow-30:crow+30+1, ccol-30:ccol+30+1] = 0
With this filter, the inverse transform is purely real (imaginary component has values in the order of 1e-13
, which is numerical errors). Thus, it is now possible (and correct) to replace img_back = np.abs(img_back)
with img_back = np.real(img_back)
.
The textbook is right, the tutorial is wrong.
A real-valued image has a complex conjugate symmetry in the Fourier domain. This means that the FFT of the image will have a specific symmetry. Any processing that you do must preserve this symmetry if you want the inverse transform to remain real-valued. If you do this processing wrong, then the inverse transform will be complex-valued, and probably non-sensical.
If you preserve the symmetry in the Fourier domain properly, then the imaginary component of the inverse transform will be nearly zero (likely different from zero because of numerical imprecision). Discarding this imaginary component is the correct thing to do. Computing the magnitude will yield the same result, except all negative values will become positive (note some filters are meant to produce negative values, such as derivative filters), and at an increased computational cost.
For example, a convolution is a multiplication in the Fourier domain. The filter in the Fourier domain must be real-valued and symmetric around the origin. Often people will confuse where the origin is in the Fourier domain, and multiply by a filter that is seems symmetric, but actually is shifted with respect to the origin making it not symmetric. This shift introduces a phase change of the inverse transform (see the shift property of the Fourier transform). The magnitude of the inverse transform is not affected by the phase change, so taking the magnitude of this inverse transform yields an output that sort of looks OK, except if one expects to see negative values in the filter result. It would have been better to correctly understand the FFT algorithm, create a properly symmetric filter in the Fourier domain, and simply keep the real part of the inverse transform.
Nonetheless, some filters are specifically designed to break the symmetry and yield a complex-valued filter output. For example the Gabor filter has an even (symmetric) component and an odd (anti-symmetric) component. The even component yields a real-valued output, the odd component yields an imaginary-valued output. In this case, it is the magnitude of the complex value that is of interest. Likewise, a quadrature filter is specifically meant to produce a complex-valued output. From this output, the analytic signal (or its multi-dimensional extension, the monogenic signal), both the magnitude and the phase are of interest, for example as used in the phase congruency method of edge detection.
Looking at the linked tutorial, it is the line
fshift[crow-30:crow+30, ccol-30:ccol+30] = 0
which generates the Fourier-domain filter and applies it to the image (it is equivalent to multiplying by a filter with 1s and 0s). This tutorial correctly computes the origin of the Fourier domain (though for Python 3 you would use crow,ccol = rows//2 , cols//2
to get the integer division). But the filter above is not symmetric around that origin. In Python, crow-30:crow+30
indicates 30 pixels to the left of the origin, and only 29 pixels to the right (the right bound is not included!). The correct filter would be:
fshift[crow-30:crow+30+1, ccol-30:ccol+30+1] = 0
With this filter, the inverse transform is purely real (imaginary component has values in the order of 1e-13
, which is numerical errors). Thus, it is now possible (and correct) to replace img_back = np.abs(img_back)
with img_back = np.real(img_back)
.
edited Nov 13 '18 at 5:16
answered Nov 12 '18 at 17:23
Cris LuengoCris Luengo
21.3k52250
21.3k52250
1
@kris: it depends on how you created the kernel. In the tutorial, they usedfftshift
on the transform, which means that the origin is in the middle of the image. Your kernel must be designed to have the origin in the same location. If your kernel is the result of an FFT of a kernel made in the spatial domain, you should applyifftshift
to the spatial-domain kernel, then applyfft
to the image and the shifted kernel, then multiply, then do the inverse transform (nofftshift
in the Fourier domain).
– Cris Luengo
Nov 12 '18 at 17:59
1
@kris: If the filter is not symmetric, then the inverse transform will be a complex-valued function. Some filters are designed this way (see the paragraph I added to the answer). It depends on the filter and how it is designed, what one does with the complex output. The discussion about symmetric filters relates to filters that are meant to keep the real-valued image being real-valued, such as low-pass, high-pass or band-pass filters.
– Cris Luengo
Nov 13 '18 at 5:19
1
The error in the OpenCV documentation has been corrected: github.com/opencv/opencv/issues/13152
– Cris Luengo
Nov 16 '18 at 2:52
1
@kris: the FT is a continuous-domain construct that requires an infinitely long signal. Sampling this signal leads to a periodic frequency domain. Now you have the DTFT (discrete time FT). Windowing the signal (when we measure a signal we don’t have infinitely long data) means we cannot apply the FT any more. So instead we assume periodicity of the signal, repeating it infinitely. Now we do have something we can compute the FT of. The periodicity leads to a discrete frequency domain. Now you have a DFT (discrete FT). The FFT computes the DFT.
– Cris Luengo
Nov 29 '18 at 14:17
1
@kris: The DSP Stack Exchange is a good place to ask questions about Fourier analysis and many other things.
– Cris Luengo
Nov 30 '18 at 6:26
|
show 12 more comments
1
@kris: it depends on how you created the kernel. In the tutorial, they usedfftshift
on the transform, which means that the origin is in the middle of the image. Your kernel must be designed to have the origin in the same location. If your kernel is the result of an FFT of a kernel made in the spatial domain, you should applyifftshift
to the spatial-domain kernel, then applyfft
to the image and the shifted kernel, then multiply, then do the inverse transform (nofftshift
in the Fourier domain).
– Cris Luengo
Nov 12 '18 at 17:59
1
@kris: If the filter is not symmetric, then the inverse transform will be a complex-valued function. Some filters are designed this way (see the paragraph I added to the answer). It depends on the filter and how it is designed, what one does with the complex output. The discussion about symmetric filters relates to filters that are meant to keep the real-valued image being real-valued, such as low-pass, high-pass or band-pass filters.
– Cris Luengo
Nov 13 '18 at 5:19
1
The error in the OpenCV documentation has been corrected: github.com/opencv/opencv/issues/13152
– Cris Luengo
Nov 16 '18 at 2:52
1
@kris: the FT is a continuous-domain construct that requires an infinitely long signal. Sampling this signal leads to a periodic frequency domain. Now you have the DTFT (discrete time FT). Windowing the signal (when we measure a signal we don’t have infinitely long data) means we cannot apply the FT any more. So instead we assume periodicity of the signal, repeating it infinitely. Now we do have something we can compute the FT of. The periodicity leads to a discrete frequency domain. Now you have a DFT (discrete FT). The FFT computes the DFT.
– Cris Luengo
Nov 29 '18 at 14:17
1
@kris: The DSP Stack Exchange is a good place to ask questions about Fourier analysis and many other things.
– Cris Luengo
Nov 30 '18 at 6:26
1
1
@kris: it depends on how you created the kernel. In the tutorial, they used
fftshift
on the transform, which means that the origin is in the middle of the image. Your kernel must be designed to have the origin in the same location. If your kernel is the result of an FFT of a kernel made in the spatial domain, you should apply ifftshift
to the spatial-domain kernel, then apply fft
to the image and the shifted kernel, then multiply, then do the inverse transform (no fftshift
in the Fourier domain).– Cris Luengo
Nov 12 '18 at 17:59
@kris: it depends on how you created the kernel. In the tutorial, they used
fftshift
on the transform, which means that the origin is in the middle of the image. Your kernel must be designed to have the origin in the same location. If your kernel is the result of an FFT of a kernel made in the spatial domain, you should apply ifftshift
to the spatial-domain kernel, then apply fft
to the image and the shifted kernel, then multiply, then do the inverse transform (no fftshift
in the Fourier domain).– Cris Luengo
Nov 12 '18 at 17:59
1
1
@kris: If the filter is not symmetric, then the inverse transform will be a complex-valued function. Some filters are designed this way (see the paragraph I added to the answer). It depends on the filter and how it is designed, what one does with the complex output. The discussion about symmetric filters relates to filters that are meant to keep the real-valued image being real-valued, such as low-pass, high-pass or band-pass filters.
– Cris Luengo
Nov 13 '18 at 5:19
@kris: If the filter is not symmetric, then the inverse transform will be a complex-valued function. Some filters are designed this way (see the paragraph I added to the answer). It depends on the filter and how it is designed, what one does with the complex output. The discussion about symmetric filters relates to filters that are meant to keep the real-valued image being real-valued, such as low-pass, high-pass or band-pass filters.
– Cris Luengo
Nov 13 '18 at 5:19
1
1
The error in the OpenCV documentation has been corrected: github.com/opencv/opencv/issues/13152
– Cris Luengo
Nov 16 '18 at 2:52
The error in the OpenCV documentation has been corrected: github.com/opencv/opencv/issues/13152
– Cris Luengo
Nov 16 '18 at 2:52
1
1
@kris: the FT is a continuous-domain construct that requires an infinitely long signal. Sampling this signal leads to a periodic frequency domain. Now you have the DTFT (discrete time FT). Windowing the signal (when we measure a signal we don’t have infinitely long data) means we cannot apply the FT any more. So instead we assume periodicity of the signal, repeating it infinitely. Now we do have something we can compute the FT of. The periodicity leads to a discrete frequency domain. Now you have a DFT (discrete FT). The FFT computes the DFT.
– Cris Luengo
Nov 29 '18 at 14:17
@kris: the FT is a continuous-domain construct that requires an infinitely long signal. Sampling this signal leads to a periodic frequency domain. Now you have the DTFT (discrete time FT). Windowing the signal (when we measure a signal we don’t have infinitely long data) means we cannot apply the FT any more. So instead we assume periodicity of the signal, repeating it infinitely. Now we do have something we can compute the FT of. The periodicity leads to a discrete frequency domain. Now you have a DFT (discrete FT). The FFT computes the DFT.
– Cris Luengo
Nov 29 '18 at 14:17
1
1
@kris: The DSP Stack Exchange is a good place to ask questions about Fourier analysis and many other things.
– Cris Luengo
Nov 30 '18 at 6:26
@kris: The DSP Stack Exchange is a good place to ask questions about Fourier analysis and many other things.
– Cris Luengo
Nov 30 '18 at 6:26
|
show 12 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53266944%2fwhy-using-magnitude-method-to-get-processed-image%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
you can only use real numbers in image, when you take inverse fourier transform it might have complex numbers as output, so you need to get real part of the inverse FT and display it as an image
– user8190410
Nov 12 '18 at 17:19
docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/….
– kris
Nov 12 '18 at 17:27
The link calculate the magnitude and the result looks great
– kris
Nov 12 '18 at 17:27