Deconvolution with OpenCV?
Sure, you can write a deconvolution Code using OpenCV. But there are no ready to use Functions (yet).
To get started you can look at this Example that shows the implementation of Wiener Deconvolution in Python using OpenCV.
Here is another Example using C, but this is from 2012, so maybe it is outdated.
Nearest neighbor deconvolution is a technique which is used typically on a stack of images in the Z plane in optical microscopy. This review paper: Jean-Baptiste Sibarita. Deconvolution Microscopy. Adv Biochem Engin/Biotechnol (2005) 95: 201–243 covers quite a lot of the techniques used, including the one you are interested in. This is also a nice intro: http://blogs.fe.up.pt/BioinformaticsTools/microscopy/
This numpy+scipy python example shows how it works:
from pylab import *
import numpy
import scipy.ndimage
width = 100
height = 100
depth = 10
imgs = zeros((height, width, depth))
# prepare test input, a stack of images which is zero except for a point which has been blurred by a 3D gaussian
#sigma = 3
#imgs[height/2,width/2,depth/2] = 1
#imgs = scipy.ndimage.filters.gaussian_filter(imgs, sigma)
# read real input from stack of images img_0000.png, img_0001.png, ... (total number = depth)
# these must have the same dimensions equal to width x height above
# if imread reads them as having more than one channel, they need to be converted to one channel
for k in range(depth):
imgs[:,:,k] = scipy.ndimage.imread( "img_%04d.png" % (k) )
# prepare output array, top and bottom image in stack don't get filtered
out_imgs = zeros_like(imgs)
out_imgs[:,:,0] = imgs[:,:,0]
out_imgs[:,:,-1] = imgs[:,:,-1]
# apply nearest neighbor deconvolution
alpha = 0.4 # adjustabe parameter, strength of filter
sigma_estimate = 3 # estimate, just happens to be same as the actual
for k in range(1, depth-1):
# subtract blurred neighboring planes in the stack from current plane
# doesn't have to be gaussian, any other kind of blur may be used: this should approximate PSF
out_imgs[:,:,k] = (1+alpha) * imgs[:,:,k] \
- (alpha/2) * scipy.ndimage.filters.gaussian_filter(imgs[:,:,k-1], sigma_estimate) \
- (alpha/2) * scipy.ndimage.filters.gaussian_filter(imgs[:,:,k+1], sigma_estimate)
# show result, original on left, filtered on right
compare_img = copy(out_imgs[:,:,depth/2])
compare_img[:,:width/2] = imgs[:,:width/2,depth/2]
imshow(compare_img)
show()
The sample image you provided actually is a very good example of Lucy-Richardson deconvolution. There is not a built-in function in OpenCV libraries for this deconvolution method. In Matlab, you may use the deconvolution with "deconvlucy.m" function. Actually, you can see the source code for some of the functions in Matlab by typing "open " or "edit ". Below, I tried to simplify the Matlab code in OpenCV.
// Lucy-Richardson Deconvolution Function
// input-1 img: NxM matrix image
// input-2 num_iterations: number of iterations
// input-3 sigma: sigma of point spread function (PSF)
// output result: deconvolution result
// Window size of PSF
int winSize = 10 * sigmaG + 1 ;
// Initializations
Mat Y = img.clone();
Mat J1 = img.clone();
Mat J2 = img.clone();
Mat wI = img.clone();
Mat imR = img.clone();
Mat reBlurred = img.clone();
Mat T1, T2, tmpMat1, tmpMat2;
T1 = Mat(img.rows,img.cols, CV_64F, 0.0);
T2 = Mat(img.rows,img.cols, CV_64F, 0.0);
// Lucy-Rich. Deconvolution CORE
double lambda = 0;
for(int j = 0; j < num_iterations; j++)
{
if (j>1) {
// calculation of lambda
multiply(T1, T2, tmpMat1);
multiply(T2, T2, tmpMat2);
lambda=sum(tmpMat1)[0] / (sum( tmpMat2)[0]+EPSILON);
// calculation of lambda
}
Y = J1 + lambda * (J1-J2);
Y.setTo(0, Y < 0);
// 1)
GaussianBlur( Y, reBlurred, Size(winSize,winSize), sigmaG, sigmaG );//applying Gaussian filter
reBlurred.setTo(EPSILON , reBlurred <= 0);
// 2)
divide(wI, reBlurred, imR);
imR = imR + EPSILON;
// 3)
GaussianBlur( imR, imR, Size(winSize,winSize), sigmaG, sigmaG );//applying Gaussian filter
// 4)
J2 = J1.clone();
multiply(Y, imR, J1);
T2 = T1.clone();
T1 = J1 - Y;
}
// output
result = J1.clone();
Here are some examples and results.
Example results with Lucy-Richardson deconvolution
Visit my blog Here where you may access the whole code.