I am trying to invert a difference of Gaussians (DoG) filter. The inverse is not stable and so I am trying to find an approximation applied to a specific input. The DoG filter increases contrast at edges, and I'm trying to find an inverse that decreases contrast at the edges.
The approximate inverse is not immediately clear and my attempts have gotten me close but not quite there.
All code is available in this Google Colab notebook.
My input is a 1D series of ascending steps. It's created as such:
luminances = np.repeat(np.linspace(0, 1, 5), 100)
My DoG filter is made with the following code:
filter_len = 81 excitatory_gaussian = scipy.signal.gaussian(filter_len, 1.4) inhibitory_gaussian = scipy.signal.gaussian(filter_len, 16) * -0.043 filter = excitatory_gaussian + inhibitory_gaussian filter /= sum(filter) plt.plot(filter)
I can create the same output with either
deconvolved_luminances = signal.convolve(luminances, filter) deconvolved_luminances = signal.lfilter(filter, , luminances)
I want to find the inverse of the DoG filter such that, when convolving this input with the inverted filter, the output is ascending steps with decreased contrast at the edges and can be convolved with my original DoG filter to output an approximate of the original input.
Seemingly because the inverse of the DoG filter isn't stable, using signal.deconvolve results in a bad output.
deconvolved_luminances, remainder = scipy.signal.deconvolve(luminances, filter)
As expected, the output is the same when using
lfilter instead of
deconvolved_luminances = scipy.signal.lfilter(, filter, luminances)
Inverting half of filter
It appears that the right half of the filter is stable. If I take this right half (
half_filter_r = filter[len(filter)//2:]) and deconvolve it with my signal (
s_deconvolved_r = signal.lfilter(, half_filter_r, s), I get a sensical output, which looks like this:
Taking the left half of the filter (
half_filter_l = filter[:len(filter)//2 + 1]) and doing the same, however, produces an output that suggests the left half of the filter is unstable:
I can assume the appropriate output of the left half is simply the inverse of the right half's output (
s_deconvolved_l = max(s_deconvolved_r) - s_deconvolved_r[::-1]) and can add this supposed left half output together with the actual right half output (
s_deconvolved_r + s_deconvolved_l) and I end up with something that looks correct:
However, assuming the left half's output based on the right half seems suspicious and seems that there should be a better way. Why would the left half be unstable while the right half is stable? Also, when I convolve my filter with the above output, I get a result that looks similar to the original filter but not quite right (hit my limit on images I'm allowed to post, but it's in the colab notebook).
Thanks for any help!