The relationship between the spatial domain filter and the frequency domain filter

Frequency domain filtering and spatial domain filtering are inextricably linked. The frequency domain filter achieves the purpose of image processing by controlling the changing frequency of the image, while the spatial domain filter achieves the effect of processing the image by convolving the template with the image matrix. It can be known from the convolution theorem that the convolution in the spatial domain is numerically equal to the inverse transformation of the product of the Fourier transform of the image and the template.

That is to say, if the template in the spatial domain is subjected to discrete Fourier transformation to obtain the template in the frequency domain, then the final result of using the spatial domain template for spatial filtering and using the obtained frequency domain template for frequency domain filtering is the same. The two methods sometimes interchangeable.

However, it should be noted that the length of the convolution result obtained by convolving the original image and the spatial template is longer than that of the original image. Even if the image and the template are filled, the first bit of the convolution result obtained is not The convolution of the template at the first pixel of the original image.

For example, assuming that the length of the p-bit original image is P, and q is the length of the convolution template, the length of the convolution template is Q. From the calculation formula of convolution, it is easy to obtain that the minimum size of the image after filling without confusion is P+Q-1. After filling, p, q for

   

Run the following program

import numpy as np
# Keep the last three digits of the significant point
np.set_printoptions(precision=3)
# Do not use scientific notation
np.set_printoptions(suppress=True)

p = np.array([[1,2,3,0,0],[4,5,6,0,0],[7,8,9,0,0],[0,0,0,0,0],[0,0,0,0,0]])
q = np.array([[1,1,1,0,0],[1,-8,1,0,0],[1,1,1,0,0],[0,0,0,0,0],[0,0,0,0,0]])
pp = np.fft.fft2(p)
qq = np.fft.fft2(q)
tt = pp*qq
t = np.fft.ifft2(tt)
print('p\n', p)
print('q\n', q)
print('t\n', t.real)

Using the convolution theorem, the result t after convolution can be obtained as

 

It can be seen from the above running results that although zero-padding can effectively avoid confusion, one thing that cannot be changed is that the size of the image after convolution will become larger. It can be seen that the result after convolution fills the entire 5×5 matrix. In theory, it is more appropriate to replace the original first pixel of the image with the convolution value of the template at the first pixel of the image (that is, 3). This result is at (1,1) of the convolution operation. In fact, the real convolution result on the image is located at the center of t, that is, the screenshot below is the filtering result of the same size as the original image.

 

Therefore, in order to obtain the same result as the spatial domain filter, when the image is extracted after filling and frequency domain filtering, the edges of the obtained processing result must be removed. Assuming that the template size is P×Q, the edge width obtained after filtering is (floor(P/2), floor(Q/2)).

 

The following is a comparison of spatial domain filtering and frequency domain filtering. The comparison steps are as follows

(1) Define a small-sized spatial domain template, and use this template to perform spatial filtering to obtain a filtered image.

(2) Calculate the filling size of the frequency domain template according to the size of the spatial domain filtering template and the original image.

(3) Fill the air domain template and multiply it by $(-1)^{x+y}$, and then perform Fourier transform to obtain the frequency domain template.

(4) Perform frequency domain filtering with the obtained frequency domain template, and intercept the filtering result.

(5) The results of spatial domain filtering and frequency domain filtering are displayed and compared.

 

The comparison code for the sobel operator is as follows

import frequency_function as fre
import airspace_filter as air
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

original_image_test4 = cv.imread('test4.tif',0)


'''Compare whether the corresponding frequency-domain filter and spatial-domain filter are equivalent'''
#
# Compare sobel operator
#
# get airspace sobel filter function
airspace_result_test1 = air.laplace_sharpen(original_image_test4, my_type='big')
# Define Spatial Filter Template
air_model = np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]])
# Calculate the size of the template after filling
shape = (2*original_image_test4.shape[0], 2*original_image_test4.shape[1])
# Fill the spatial domain template to the corresponding size, transform to frequency domain template and move the low frequency to the center
fre_model = np.fft.fft2(fre.my_get_fp(fre.my_fill(air_model, shape)))
# Frequency Domain Filtering with Frequency Domain Templates
frequency_result_test1 = fre.myfunc_seldifine(original_image_test4, fre_model, output_offset=(1, 1))
# Convert the pixel value of the filtered result to 0~255
airspace_result_test1=air.show_edge(airspace_result_test1)
frequency_result_test1=air.show_edge(frequency_result_test1)

# The results show
plt.subplot(131)
plt.imshow(original_image_test4)
plt.title('original')
plt.subplot(132)
plt.imshow(airspace_result_test1)
plt.title('spatial filter')
plt.subplot(133)
plt.imshow(frequency_result_test1)
plt.title('frequency filter')
plt.show()

The comparison result is

 

It can be seen that the effect of the two methods is the same.

 

Comparison code for Gaussian low pass filtering

import frequency_function as fre
import airspace_filter as air
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

original_image_test1 = cv.imread('test1.pgm',0)
original_image_test2 = cv.imread('test2.tif',0)
original_image_test3 = cv.imread('test3_corrupt.pgm',0)
original_image_test4 = cv.imread('test4.tif',0)

#
# Compare Gaussian Filters
#
# Get the spatial Gaussian filter function
airspace_result_test1 = air.gaussion_blur_gray(original_image_test1, 7, 1.5)
# Get the spatial Gaussian filter template
air_model = air.get_gaussion_blur_retric(7, 1.5)
# Calculate the size of the template after filling
shape = (original_image_test1.shape[0] + 7, original_image_test1.shape[1] + 7)
# Fill the spatial domain template to the corresponding size, transform to frequency domain template and move the low frequency to the center
fre_model = np.fft.fft2(fre.my_get_fp(fre.my_fill(air_model, shape)))
# Frequency Domain Filtering with Frequency Domain Templates
frequency_result_test1 = fre.myfunc_seldifine(original_image_test1, fre_model, output_offset=(3, 3))

# Filter result display
plt.subplot(131)
plt.imshow(original_image_test1)
plt.title('original')
plt.subplot(132)
plt.imshow(airspace_result_test1)
plt.title('spatial filter')
plt.subplot(133)
plt.imshow(frequency_result_test1)
plt.title('frequency filter')
plt.show()

The comparison result is

 

Posted by koldstar on Wed, 25 May 2022 20:50:54 +0300