Search code examples
pythonarraysnumpyimage-processingconvolution

Convolution on Python


So I suppose to calculate the convolution between Fourier Transformed image and the mask.

from scipy import fftpack
import numpy as np
import imageio
from PIL import Image, ImageDraw
import cv2
import matplotlib.pyplot as plt
import math
from scipy.ndimage.filters import convolve


input_image = Image.open('....image....')
input_image=np.array(input_image)
M,N = input_image.shape[0],input_image.shape[1]

FT_img = fftpack.fftshift(fftpack.fft2(input_image))

n = 2; # order value can change this value accordingly 


D0 = 60; # cut-off frequency can change this value accordingly 

# Designing filter 

u = np.arange(0, M)
idx = u > M/2
u[idx] = u[idx] - M
v = np.arange(0, N)
idy = v > N/2
v[idy] = v[idy] - N

V,U = np.meshgrid(v,u)

# Calculating Euclidean Distance 
D=np.linalg.norm(V-U) 

# determining the filtering mask 
H = 1/(1 + (D0/D)**(2*n)); 

# Convolution between the Fourier Transformed image and the mask 
G = convolve(H, FT_img)

And I get "Runtime error:filter weights array has incorrect shape." error at the last line when I run this code snippet. What I understand is H is float and FT_img is array so I cannot perform convolution on these. But I don't know how to solve that. How can I solve this problem?


Solution

  • calculating distance D, and filter H for each (u, v) this will yield an array with same size of input image, multiplying that array(H the Filter) with the image in Fourier Domain will be equivalent to convolution in the Time domain, and the results will be as following:

    results

    import numpy as np
    import cv2
    import matplotlib.pyplot as plt
    
    # Read Image as Grayscale
    img = cv2.imread('input.png', 0)
    
    # Designing filter 
    #------------------------------------------------------
    def butterworth_filter(shape, n=2, D0=60):
        '''
        n = 2; # order value can change this value accordingly 
        D0 = 60; # cut-off frequency can change this value accordingly 
        '''
        M, N = shape
        # Initialize filter with zeros
        H = np.zeros((M, N))
    
        # Traverse through filter
        for u in range(0, M):
            for v in range(0, N):
                # Get euclidean distance from point D(u,v) to the center
                D_uv = np.sqrt((u - M / 2) ** 2 + (v - N / 2) ** 2)
                # determining the filtering mask 
                H[u, v] = 1/(1 + (D0/D_uv)**(2*n))
        return H
    #-----------------------------------------------------
    
    f = np.fft.fft2(img)
    fshift = np.fft.fftshift(f)
    phase_spectrumR = np.angle(fshift)
    magnitude_spectrum = 20*np.log(np.abs(fshift))
     
    # Generate Butterworth Filter
    H = butterworth_filter(img.shape)
    # Convolution between the Fourier Transformed image and the mask
    G = H * fshift
    # Obtain the Result
    result = np.abs(np.fft.ifft2(np.fft.ifftshift((G))))
    
    
    plt.subplot(222)
    plt.imshow(img, cmap='gray')
    plt.title('Original')
    plt.axis('off')
    
    plt.subplot(221)
    plt.imshow(magnitude_spectrum, cmap='gray')
    plt.title('magnitude spectrum')
    plt.axis('off')
    
    plt.subplot(223)
    plt.imshow(H, "gray") 
    plt.title("Butterworth Filter")
    plt.axis('off')
    
    plt.subplot(224)
    plt.imshow(result, "gray") 
    plt.title("Result")
    plt.axis('off')
    
    plt.show()