Learn Python image processing with me丨Take you to master the principle and implementation of Fourier transform

Abstract: Fourier transform mainly transforms the signal in the time domain into the signal in the frequency domain, which is used for image denoising, image enhancement and other processing.

This article is shared from Huawei Cloud Community " [Python Image Processing] 22. Principle and Implementation of Fourier Transform of Python Image ", author: eastmount.

This article mainly explains the related content of image Fourier transform. In digital image processing, there are two classic transforms that are widely used - Fourier transform and Hough transform. Among them, Fourier transform mainly converts the signal in the time domain into the signal in the frequency domain, which is used for image denoising, image enhancement and other processing.

Image Fourier Transform Principle

Fourier Transform (Fourier Transform, FT for short) is often used in digital signal processing, and its purpose is to convert a signal in the time domain into a signal in the frequency domain. As the domain is different, the understanding angle of the same thing also changes, so some places that are difficult to deal with in the time domain can be handled relatively simply in the frequency domain. At the same time, some previously imperceptible features can be found in the frequency domain. Fourier's theorem states that "any continuous periodic signal can be represented (or infinitely approximated) as a superposition of a series of sinusoidal signals."

The following is a case from Mr. Li's "Python+OpenCV Image Processing", which is highly recommended for students to learn. As shown in the figure below, he converted the time domain angle of a beverage production process into a frequency domain angle.

Plot the corresponding time graph and frequency graph as follows:

The Fourier formula is as follows, where w represents frequency and t represents time, which is a complex function. It expresses the function in the time domain as the integral of the function f(t) in the frequency domain.

Fourier transform considers that a periodic function (signal) contains multiple frequency components, and any function (signal) f(t) can be synthesized by adding multiple periodic functions (or basis functions). From a physical point of view, Fourier transform takes a set of special functions (trigonometric functions) as an orthogonal basis, and performs linear transformation on the original function. The physical meaning is the projection of the original function on each group of basis functions. As shown in the figure below, it is composed of three sinusoids.

Fourier transform can be applied to image processing, and its spectrogram can be obtained by transforming the image. The intensity of grayscale changes in the image is characterized by the frequency in the spectrogram. The edge signals and noise signals in the image are often high frequency signals, while the image contours and background signals with frequent changes in the image are often low frequency signals. At this time, relevant operations can be performed on the image in a targeted manner, such as image denoising, image enhancement and sharpening.

The Fourier transform of a two-dimensional image can be expressed by the following mathematical formula (15-3), where f is the value in the spatial domain (Spatial Domain) and F is the value in the frequency domain (Frequency Domain)

After having a general understanding of the above Fourier transform, the algorithm and operation code of the image Fourier transform will be explained through Numpy and OpenCV respectively.

2. Numpy implements Fourier transform

The FFT package in Numpy provides the function np.fft.fft2() to perform fast Fourier transform on the signal. The function prototype is as follows, and the output result is a complex array (Complex Ndarry).

fft2(a, s=None, axes=(-2, -1), norm=None)

  • a represents the input image, an array-like complex array
  • s represents a sequence of integers and can determine the size of the output array. Output optional shape (length of each transformed axis), where s[0] represents axis 0 and s[1] represents axis 1. Corresponding to n in the fit(x,n) function, along each axis, if the given shape is smaller than the input shape, the input will be clipped. If it is greater than then the input will be padded with zeros. If 's' is not given, the input shape along the axes specified by 'axles' is used
  • axes represents a sequence of integers, optional axes for computing the FFT. If not given, the last two axes are used. Repeated indices in "axes" means performing multiple transformations for that axis, a sequence of elements means performing a 1D FFT
  • norm includes options None and ortho, the normalization mode (see numpy.fft). Default is None

The fft module in Numpy has many functions. The related functions are as follows:

#Calculate the one-dimensional Fourier transform
numpy.fft.fft(a, n=None, axis=-1, norm=None) #Calculate
the two-dimensional Fourier transform
numpy.fft.fft2(a, n=None, axis=-1, norm=None) #Calculate
the Fourier transform of n-dimensional
numpy.fft.fftn() #Calculate the Fourier transform
of n-dimensional real numbers Frequency numpy.fft.fftfreq() #shift the DC component in the FFT output to the center of the spectrum numpy.fft.shift()




The following code implements Fourier transform through Numpy library, calls np.fft.fft2() fast Fourier transform to get frequency distribution, then calls np.fft.fftshift() function to transfer the center position to the middle, and finally passes Matplotlib Display renderings.

# -*- coding: utf-8 -*-
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
#读取图像
img = cv.imread('test.png', 0)
#快速傅里叶变换算法得到频率分布
f = np.fft.fft2(img)
#默认结果中心点位置是在左上角,
#调用fftshift()函数转移到中间位置
fshift = np.fft.fftshift(f) 
#fft结果是复数, 其绝对值结果是振幅
fimg = np.log(np.abs(fshift))
#展示结果
plt.subplot(121), plt.imshow(img, 'gray'), plt.title('Original Fourier')
plt.axis('off')
plt.subplot(122), plt.imshow(fimg, 'gray'), plt.title('Fourier Fourier')
plt.axis('off')
plt.show()

The output result is shown in Figure 15-2. The left is the original image, and the right is the frequency distribution map. The closer to the center, the lower the frequency, and the brighter (higher gray value) position represents the greater the signal amplitude of the frequency.

3. Numpy implements inverse Fourier transform

The following describes how Numpy implements inverse Fourier transform, which is the inverse operation of Fourier transform, the process of converting a spectral image into an original image. It will be converted into a spectrogram by Fourier transform, and the high frequency (boundary) and low frequency (detail) parts will be processed, and then it needs to be restored to the original rendering by inverse Fourier transform. The processing of the image in the frequency domain will be reflected in the inversely transformed image, so that the image processing is better.

The main functions used for the Fourier transform of an image are as follows:

#Implement the inverse Fourier transform of the image and return a complex array
numpy.fft.ifft2(a, n=None, axis=-1, norm=None)
#The inverse function of the fftshit() function, it will be the center low frequency of the spectrum image Partially moved to the upper left corner
numpy.fft.fftshift() #Convert
complex numbers to the range 0 to 255
iimg = numpy.abs (inverse Fourier transform result)

The code below implements the Fourier transform and the inverse Fourier transform, respectively.

# -*- coding: utf-8 -*-
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
#读取图像
img = cv.imread('Lena.png', 0)
#傅里叶变换
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
res = np.log(np.abs(fshift))
#傅里叶逆变换
ishift = np.fft.ifftshift(fshift)
iimg = np.fft.ifft2(ishift)
iimg = np.abs(iimg)
#展示结果
plt.subplot(131), plt.imshow(img, 'gray'), plt.title('Original Image')
plt.axis('off')
plt.subplot(132), plt.imshow(res, 'gray'), plt.title('Fourier Image')
plt.axis('off')
plt.subplot(133), plt.imshow(iimg, 'gray'), plt.title('Inverse Fourier Image')
plt.axis('off')
plt.show()

The output results are shown in Figure 15-4, from left to right are the original image, spectrum image, and inverse Fourier transform transformed image.

Four. OpenCV implements Fourier transform

The corresponding function in OpenCV is cv2.dft() and the output with Numpy is the same, but with two channels. The first channel is the real part of the result, the second channel is the imaginary part of the result, and the input image is first converted to np.float32 format. Its function prototype is as follows:

dst = cv2.dft(src, dst=None, flags=None, nonzeroRows=None)

  • src represents the input image, which needs to be converted by np.float32
  • dst represents the output image, including output size and dimensions
  • flags represents conversion flags, where DFT _INVERSE performs an inverse 1D or 2D transformation instead of the default forward transformation; DFT _SCALE represents the scaling result, divided by the number of array elements; DFT _ROWS performs a forward or reverse transformation Each individual row of the input matrix, this flag can transform multiple vectors at the same time, and can be used to reduce overhead to perform 3D and higher dimensional transformations, etc.; DFT _COMPLEX_OUTPUT performs forward transformation of 1D or 2D real arrays, which is the most fast choice, default function; DFT _REAL_OUTPUT performs the inverse transform of a 1D or 2D complex array, the result is usually a complex array of the same size, but if the input array has conjugate complex symmetry, the output is a real array
  • nonzeroRows means that when the argument is nonzero, the function assumes that only the first row of the nonzeroRows input array (unset) or only the first (set) of the output array contains nonzeros, so the function can process the rest of the rows more efficiently, and Save some time; this technique is useful for computing array cross-correlation or using DFT convolution

Note that since the output spectral result is a complex number, the cv2.magnitude() function needs to be called to convert the two-channel result of the Fourier transform to a range of 0 to 255. Its function prototype is as follows:

cv2.magnitude(x, y)

  • x represents the floating-point X coordinate value, that is, the real part
  • y represents the floating-point Y coordinate value, that is, the imaginary part
    The final output result is the amplitude value, that is:

The complete code looks like this:

# -*- coding: utf-8 -*-
import numpy as np
import cv2
from matplotlib import pyplot as plt
#读取图像
img = cv2.imread('Lena.png', 0)
#傅里叶变换
dft = cv2.dft(np.float32(img), flags = cv2.DFT_COMPLEX_OUTPUT)
#将频谱低频从左上角移动至中心位置
dft_shift = np.fft.fftshift(dft)
#频谱图像双通道复数转换为0-255区间
result = 20*np.log(cv2.magnitude(dft_shift[:,:,0], dft_shift[:,:,1]))
#显示图像
plt.subplot(121), plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(result, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()

The output is shown in Figure 15-5, with the original "Lena" image on the left and the converted spectrum image on the right, with the low frequencies at the center.

Five. OpenCV implements inverse Fourier transform

In OpenCV, the inverse Fourier transform is implemented by the function cv2.idft(), and the return result depends on the type and size of the original image, which can be real or complex. Its function prototype is as follows:

dst = cv2.idft(src[, dst[, flags[, nonzeroRows]]])

  • src represents the input image, including real or complex numbers
  • dst represents the output image
  • flags represents conversion flags
  • nonzeroRows represents the number of dst rows to process, the content of the remaining rows is undefined (see convolution example in dft description)

The complete code looks like this:

# -*- coding: utf-8 -*-
import numpy as np
import cv2
from matplotlib import pyplot as plt
#读取图像
img = cv2.imread('Lena.png', 0)
#傅里叶变换
dft = cv2.dft(np.float32(img), flags = cv2.DFT_COMPLEX_OUTPUT)
dftshift = np.fft.fftshift(dft)
res1= 20*np.log(cv2.magnitude(dftshift[:,:,0], dftshift[:,:,1]))
#傅里叶逆变换
ishift = np.fft.ifftshift(dftshift)
iimg = cv2.idft(ishift)
res2 = cv2.magnitude(iimg[:,:,0], iimg[:,:,1])
#显示图像
plt.subplot(131), plt.imshow(img, 'gray'), plt.title('Original Image')
plt.axis('off')
plt.subplot(132), plt.imshow(res1, 'gray'), plt.title('Fourier Image')
plt.axis('off')
plt.subplot(133), plt.imshow(res2, 'gray'), plt.title('Inverse Fourier Image')
plt.axis('off')
plt.show()

The output results are shown in Figure 15-6. The first picture is the original "Lena" picture, the second picture is the spectral image after Fourier transform, and the third picture is the inverse Fourier transform. The spectral image is converted to The process of the original image.

6. Summary

The purpose of Fourier transform is not to observe the frequency distribution of the image (at least not the final purpose), but in more cases to filter the frequency, by modifying the frequency to achieve image enhancement, image denoising, edge detection, feature extraction, Compression encryption and other purposes. In the next article, the author will combine the Fourier transform and the inverse Fourier transform to explain its application.

 

Click Follow to learn about HUAWEI CLOUD's new technologies for the first time~

{{o.name}}
{{m.name}}

Guess you like

Origin my.oschina.net/u/4526289/blog/5580251