|
| 1 | +r""" |
| 2 | +SV_DECONV |
| 3 | +===== |
| 4 | +This example implements the saptially varying PSF deconvolution algorithm |
| 5 | +based on: Flicker & Rigaut, 2005 https://doi.org/10.1364/JOSAA.22.000504 |
| 6 | +""" |
| 7 | + |
| 8 | +import numpy as np |
| 9 | +from pylops import LinearOperator |
| 10 | +from scipy.signal import fftconvolve |
| 11 | +from pylops.basicoperators import FunctionOperator |
| 12 | +from pylops.utils import dottest |
| 13 | +from functools import partial |
| 14 | + |
| 15 | +############################################################################### |
| 16 | +# Sample data |
| 17 | +im = np.random.randn(2748, 3840) |
| 18 | +W = np.random.randn(20, np.prod(im.shape)) |
| 19 | +U = np.random.randn(np.prod(im.shape), 20) |
| 20 | + |
| 21 | +# Setup Custom Linear Operator with Forward and Adjoint Models |
| 22 | +# A) Using Function Operator |
| 23 | +def forward(im, U, W, im_shape): |
| 24 | + im = im.reshape(*im_shape) |
| 25 | + for i in range(15): |
| 26 | + weight = W[i,:].reshape(*im_shape) |
| 27 | + psf_mode = U[:,i].reshape(*im_shape) |
| 28 | + im += fftconvolve(im* weight, psf_mode) |
| 29 | + return im.ravel() |
| 30 | + |
| 31 | +def forward_c(im, U, W, im_shape): |
| 32 | + im = im.reshape(*im_shape) |
| 33 | + for i in range(15): |
| 34 | + weight = W[i,:].reshape(*im_shape) |
| 35 | + psf_mode = U[:,i].reshape(*im_shape) |
| 36 | + im += fftconvolve(im, np.flipud(np.fliplr(psf_mode)))* weight #psf_mode[::-1, ::-1] |
| 37 | + return im.ravel() |
| 38 | + |
| 39 | +A = FunctionOperator(partial(forward, U=U, W=W, im_shape=im.shape), partial(forward_c, U, W, im_shape=im.shape), im.shape[0], im.shape[1]) |
| 40 | +print(dottest(A, im.shape[0], im.shape[1])) |
| 41 | + |
| 42 | + |
| 43 | + |
| 44 | +# # Using Linear Opeartor Class |
| 45 | +# class Blur(LinearOperator): |
| 46 | +# def __init___(self, shape): |
| 47 | +# super().__init__(shape=shape) |
| 48 | + |
| 49 | +# def _matvec(self, im): |
| 50 | +# im = im.reshape(self.shape) |
| 51 | +# for i in range(15): |
| 52 | +# weight = W[i,:].reshape(*self.shape) |
| 53 | +# psf_mode = U[:,i].reshape(*self.shape) |
| 54 | +# im += fftconvolve(im* weight, psf_mode) |
| 55 | +# return im.ravel() |
| 56 | + |
| 57 | +# def _rmatvec(self, im): |
| 58 | +# im = im.reshape(self.shape) |
| 59 | +# for i in range(15): |
| 60 | +# weight = W[i,:].reshape(*self.shape) |
| 61 | +# psf_mode = U[:,i].reshape(*self.shape) |
| 62 | +# im += fftconvolve(im, psf_mode[::-1, ::-1])* weight |
| 63 | +# return im.ravel() |
| 64 | + |
| 65 | +# Op = Blur(shape=im.shape, dtype=float) |
| 66 | +# print(dottest(Op, nr=im.shape[0], nc=im.shape[1])) |
0 commit comments