Reputation: 1178
I'm convolving a signal f
, with a kernel h
, in spatial domain, then, I'm deconvolving in frequency domain. Since I know the kernel h
, in theory I should be able to get f
back without any problem, however, it's not working. This is what I have:
from scipy.fft import fft, ifft, fftfreq, fft2, ifft2, fftshift, ifftshift
from scipy.ndimage import convolve
d = 11 # diameter of image
f = np.zeros((d, d))
r = 1 # radius of line
f[d//2-1: d//2+r+1] = 1 # image with a line
f[d//2, d//2] = 0 # and 0 at the center
f[0, 0] = 2 # and a 2 at top left corner
print("\nf =")
print(f)
h = np.zeros_like(f)
h[d//2-1, d//2-1] = h[d//2, d//2] = h[d//2+1, d//2+1] = 1 # identity filter
print("\nh =")
print(h)
g = convolve(f, h) # conv spatial domain
G = fft2(g)
H = fft2(h) # fft of filter
f_approx = fftshift(ifft2(G/H)) # deconvolution
print("\nf^approx =")
print(np.round(f_approx.real, 2))
This is the output:
f =
[[2. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 0. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
h =
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
f^approx =
[[ 0. -0.67 -0. -0. -0. -0. -0. -0. -0. -0. 1.33]
[-0.67 2. 1.33 0. -0. -0. -0. 0. -0. 0. -0. ]
[-0. 1.33 0. -0.67 -0. -0. 0. 0. -0. 0. -0. ]
[-0. 0. -0.67 -2. -0.67 0. -0. -0. -0. -0. -0. ]
[ 1. 1. 1. 0.33 3. 2.33 1. 1. 1. 1. 1. ]
[ 1. 1. 1. 1. 2.33 0. 0.33 1. 1. 1. 1. ]
[ 1. 1. 1. 1. 1. 0.33 -1. 0.33 1. 1. 1. ]
[-0. 0. 0. 0. -0. 0. -0.67 2. 1.33 -0. 0. ]
[-0. -0. 0. -0. -0. -0. -0. 1.33 -0. -0.67 -0. ]
[ 0. 0. 0. -0. 0. -0. 0. 0. -0.67 -2. -0.67]
[ 1.33 -0. -0. -0. 0. 0. 0. -0. -0. -0.67 2. ]]
Why am I not getting the original f
back? Am I using the functions incorrectly, or is there some problem with the approach? Thanks
PS: by the way, if the h
is the identity, then the deconvolution works fine, the problem is when the filter is something else.
Upvotes: 2
Views: 393
Reputation: 1178
Thanks @chris-luengo. Also, thanks to Ahmed.
I guess this would be it, then:
from scipy.fft import fft, ifft, fftfreq, fft2, ifft2, fftshift, ifftshift
from scipy.ndimage import convolve
d = 11 # diameter of image
f = np.zeros((d, d))
r = 1 # radius of line
f[d//2-1: d//2+r+1] = 1 # image with a line
f[d//2, d//2] = 0 # and 0 at the center
f[0, 0] = 2 # and a 2 at top left corner
print("\nf =")
print(f)
h = np.zeros_like(f)
h[d//2-1, d//2-1] = h[d//2, d//2] = h[d//2+1, d//2+1] = 1
print("\nh =")
print(h)
g = convolve(f, h, mode="wrap") # conv spatial domain
G = fft2(g)
H = fft2(ifftshift(h)) # fft of filter
f_approx = ifft2(G/H) # deconvolution
print("\nf^approx =")
print(np.round(f_approx.real, 2))
I hope it's useful to someone ;)
Upvotes: 2