2

In Solving inverse problem using black box implementation of the kernel the solution depends on solving the equations of the form:

$${\left( {H}^{T} H + \lambda {G}^{T} G \right)} x = y$$

Where $H$ and $G$ represent convolution operation of the $h$ and $g$ kernels.

Given we have a a black box implementation of the convolution by $h$ and $g$, how can we solve those equations efficiently?

Those forms are very common in many image processing algorithms and solving them by the matrix representation is not efficient.

Marcus Müller
  • 30,525
  • 4
  • 34
  • 58
Eric Johnson
  • 324
  • 1
  • 3
  • 16
  • The inverse operation is called deconvolution. Classical method are Richardson-Lucy and Iterative Constrained Tikhonov-Miller. There are some newer solutions, such as Fast Iterative Shrinkage Thresholding (FISTA). – Cris Luengo Apr 14 '23 at 23:56
  • @CrisLuengo, If you look at the context he used, the idea is as following, if you have a kernel $ \boldsymbol{h} $ and $ \boldsymbol{g} $, how do you apply above fast using convolution operations. – Royi Apr 15 '23 at 05:52
  • @Royi If you look up the above methods, they're always implemented using the FFT. There are lots of implementations out there to use (or just to look at if OP insists in implementing it themselves). – Cris Luengo Apr 15 '23 at 07:31
  • @CrisLuengo, If you look on the context of the answer it is something like the FISTA model (TV regularization) yet with ADMM which is even faster than the accelerated proximal gradient descent in FISTA. – Royi Apr 15 '23 at 16:57

1 Answers1

3

This is not an easy question, not because ideas are complex but since the details matter a lot.

As I wrote in my answer in the question Solving Inverse Problem Using Black Box Implementation of the Convolution Kernel, the issue is defining how to handle the boundaries (See The Different Solutions for Filter Coefficients Estimation for Periodic Convolution and Full Convolution). This is super important for images.

Matrix Case

In all cases, for this equation:

$$ {\left( {H}^{T} H + \lambda {G}^{T} G \right)} \boldsymbol{x} = \boldsymbol{y} \Leftrightarrow A \boldsymbol{x} = \boldsymbol{y} $$

Can be solved using sparse solvers taking advantage of the sparsity pattern of the matrices and the matrix being symmetric positive definite.

This will work for any variant of the convolution.
Though we have 2 options, direct solvers and iterative ones.

The iterative ones allow us taking advantage of the convolution black box as they usually require applying the operator $ A $. Many iterative solvers require $ {A}^{T} $ but if they do, it means they don't model it as a symmetric operator. Hence it means they are not optimal. So stick with those assuming symmetric operator, hence require $ A $ only.

Now the question, how to implement $ A $ efficiently?

Periodic / Cyclic Boundary Conditions

If we assume that the $ \ast $ (Convolution) is applied using cyclic boundary convolution we can apply everything in frequency domain.
I wrote many answer about it, you may look at them:

The Convolution of Type full / same / valid

For the other convolution types (I Use the lingo of MATLAB's convolution functions, such as conv2()) things are trickier.

I created the matrix $ {H}^{T} H $ for the different convolution shapes from the same 3 coefficients kernel applied on 5 samples signal:

enter image description here

As one can see, while all cases generates a 5x5 matrix, yet only the full case generates a Toeplitz Matrix.
Hence, only this case can be represented by a convolution kernel with some convolution type.

General Solution

We can always apply each matrix by itself. Something like:

$$ {\left( {H}^{T} H + \lambda {G}^{T} G \right)} \boldsymbol{x} = {H}^{T} \left( H \boldsymbol{x} \right) + \lambda {G}^{H} \left( G \boldsymbol{x} \right) $$

So $ H \boldsymbol{x} $ / $ G \boldsymbol{x} $ is just applying the convolution, what about $ {H}^{T} \boldsymbol{z} $ / $ {G}^{T} \boldsymbol{z} $? Well, we can have a recipe per case, where the adjoint is done by the flipped kernel:

  • Convolution Type full -> Correlation type valid.
  • Convolution Type same -> Correlation type same.
  • Convolution Type valid -> Correlation type full.

Now we can apply all of the above one by one.

Optimized Solution for full

As we can see, in case our convolution is of type full the normal matrix $ {H}^{T} H $ is a Toeplitz Matrix, so we can generate the composite operation using a single kernel convolution.

Results

I implemented all cases above and using Conjugate Gradient I got the following results for 1D:

enter image description here

As can be seen, we can get the same results using the iterative method.
This method only applies convolution operations and doesn't require the matrix form.

Some Other Resources

Royi
  • 19,608
  • 4
  • 197
  • 238
  • 1
    You can get around the periodic boundary condition of the FFT-based convolution by simply padding the image a bit. This is a fairly standard procedure, I think? – Cris Luengo Apr 15 '23 at 07:32
  • $H^TH$ translates to $H^*H = |H|^2$ if $H$ is the Fourier transform of the kernel, rather than the convolution matrix. – Cris Luengo Apr 15 '23 at 07:35
  • I wrote that I don't take care of the DFT in this answer as I wrote about it in many other places (I linked, some include the extension trick). I am not sure it will be faster from using the full method. I am working on extending the answer. – Royi Apr 15 '23 at 16:55
  • @CrisLuengo, Does you library have something like that pre defined as a function? I am talking about generating this in Fourier domain using the proper padding and afterwards proper extraction of the signals? – Royi Apr 16 '23 at 07:21
  • There’s several deconvolution algorithms, they all use the Fourier domain for convolution using proper padding etc. – Cris Luengo Apr 16 '23 at 13:34
  • 1
    @CrisLuengo, OK. Let's see if the OP is interested in it. Then I might compare high level results to your code (I read it has Python / MATLAB wrapper, I don't "speak" C++ :)). – Royi Apr 16 '23 at 14:36
  • @CrisLuengo, I found that 2 years ago I implemented this in https://dsp.stackexchange.com/questions/74803. I still don't see the way to apply the whole operator in frequency for the case of non full convolution. I'd argue it can not be done as the operators don't even generate a Toeplitz Matrix. Are you sure you can apply the whole operator $ {\left( {H}^{T} H + \lambda {G}^{T} G \right)} $ at once for the case of valid or same convolution operator? – Royi Apr 17 '23 at 10:04
  • Neither of those three methods are really useful in image processing. valid is the only sensical method, but it assumes pixels outside the frame are 0, which usually causes strong edge effects. It is better to use a different boundary condition, such as mirroring. Still, I don’t see the difference between that compound operator and any other convolution operation. – Cris Luengo Apr 17 '23 at 13:32
  • @CrisLuengo, Working with boundary (I usually prefer replicate) is equivalent to padding and then valid convolution. This is the context it will work. Actually the latest crop of the pre deep learning methods usually assumed valid convolution. Pay attention that the matrix of the boundaries will not generate a Toeplitz / Block Toeplitz matrix which again can not be approximated, even with padding, in frequency. So it means you need to actually pad and work with the new one. For full convolution, no problem. – Royi Apr 17 '23 at 17:35
  • @CrisLuengo, By the way valid is not equivalent to zero boundary, it is full which is equivalent to zero boundary conditions. – Royi Apr 17 '23 at 17:36
  • I meant “same” is the only sensical method — Typo! You need the output to be the same size as the input more often than not. – Cris Luengo Apr 17 '23 at 17:54
  • Anyway, the convolution matrix is a great way to think about the problem, and figure out optimization schemes, but it’s not a good way to implement anything. And the implementation doesn’t need to match what the matrix does at the edges, that is totally uninteresting. In an actual implementation you handle the edges in the way that gives them least impact on the result. In an ideal world, the images are infinite in size and we don’t need to deal with the edges. :) – Cris Luengo Apr 17 '23 at 17:58
  • @CrisLuengo, I am aware of the concept and have worked by it. Still, without actually padding the data which means allocations, I don't see how you can do this in frequency domain unless you assume cyclic or full convolution. – Royi Apr 17 '23 at 18:20
  • Regarding the boundaries, I think differently. How we model them has a great effect on the deconvolution. Hence we must handle them carefully which is why, to my knowledge, the most advanced methods don't solve those equations in frequency domain. See for instance: https://i.imgur.com/dE94Xjk.png. Once you have the mask, the composition can not be calculated in frequency (Unless you do some tricks, for another time). – Royi Apr 17 '23 at 18:29
  • @CrisLuengo, I explained what I mean in https://dsp.stackexchange.com/questions/87582. I'd be happy for you feedback. – Royi Apr 18 '23 at 07:42
  • Yes, how you handle the boundary has a very big effect on the result. But the convolution we’re trying to undo was applied to a continuous-domain to image which was then windowed and sampled. The convolution “mode” as defined in MATLAB is not part of the deconvolution problem, though the image edge is an additional problem that needs to be overcome. – Cris Luengo Apr 18 '23 at 14:06
  • @CrisLuengo, Totally agree. But at the end, we need to model something. From the same reasoning you present, I think the bets model was to use valid. Then the "unknown" part has to be estimated (Then will be discarded). – Royi Apr 18 '23 at 14:08
  • Sure, but discard the image edges only at the very end, not at every convolution in the iterative processes. The longer you iterate, the less result you’re left with!!! – Cris Luengo Apr 18 '23 at 14:13
  • @CrisLuengo, Even if it iterative, you usually pad, convolution with valid then the output is of the same dimensions. – Royi Apr 18 '23 at 14:16
  • Right, so then you apply a different boundary condition than what is provided by conv. That is the same as using “same” with a better padding than zeros. In an iterative process, it is best to pad once, and not crop until the very end. The padding contains a bit of information after the convolution, throwing that away after each step is not as good as keeping until the end. – Cris Luengo Apr 18 '23 at 14:26