Intel® Integrated Performance Primitives
Community support and discussions relating to developing high-performance vision, signal, security, and storage applications.
Announcements
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!

DeconvLR

Petric__Sinisa
Beginner
143 Views
Hi, I've checked forum posts regarding Lucy-Richardson deconvolution, but I still can acquire "reasonable" results. An input image is 3-channels RGB image (output image is the same with same dimensions), so I must first convert input image to 32f, run deconvolution and then convert resultant 32f image to 8u output image. Here is the code that I use to perform LR Deconvolution: --------------------------------------------------------- int ippProcess::DeconvolveLR(ippImage *srcImage, ippImage *dstImage, TRect *roiRect, int kernelSize, float threshold, int numIter) { // calculate srcStep/dstStep/roiSize with respect to roiRect prepareData(srcImage, dstImage, roiRect); IppStatus status; Ipp32f thr = threshold /255.0; IppiSize maxRoi; maxRoi.width = roiSize.width + kernelSize; maxRoi.height = roiSize.height + kernelSize; IppiDeconvLR_32f_C3R *pDeconvLR = 0; int pSize; status = ippiDeconvLRGetSize_32f(3, kernelSize, maxRoi, &pSize); if (status) return status; pDeconvLR = (IppiDeconvLR_32f_C3R *)ippsMalloc_32f(pSize); Ipp32f *kernel = new Ipp32f[kernelSize*kernelSize]; // fill the PSF with ones for (int i = 0; i < kernelSize*kernelSize; i++) kernel = 1; status = ippiDeconvLRInit_32f_C3R(pDeconvLR, kernel, kernelSize, maxRoi, thr); if (status) { delete []kernel; ippsFree(pDeconvLR); return status; } int interStepIn, interStepOut; Ipp32f *interImageIn = ippiMalloc_32f_C3(maxRoi.width, maxRoi.height, &interStepIn); Ipp32f *interImageOut = ippiMalloc_32f_C3(roiSize.width, roiSize.height, &interStepOut); // status = ippiConvert_8u32f_C3R(pSrc, srcStep, interImageIn, interStepIn, roiSize); // convert forward status = ippiDeconvLR_32f_C3R(interImageIn, interStepIn, interImageOut, interStepOut, roiSize, numIter, pDeconvLR); if (!status) ippiConvert_32f8u_C3R(interImageOut, interStepOut, pDst, dstStep, roiSize, ippRndNear); // convert backward ippsFree(pDeconvLR); ippiFree(interImageIn); ippiFree(interImageOut); delete []kernel; return status; } --------------------------------------------- However, resulting image has some strange artifacts on the image border. Also, for larger kernel sizes and larger iterations number (>= 5) output image looks embossed and the effect of color channels shifting arises. From the documentation, it's not clear does DeconvLR operate on scaled f32 images (I've tried scaling as well), what is the range of threshold parameter and how the input image should be "placed" inside maxRoi. If someone can detect the error in my code, it would be helpful. TIA
0 Kudos
3 Replies
Igor_A_Intel
Employee
143 Views

Hi Petric,

as it's mentioned in the manual - "border pixels of a source image are restored before deconvolution." In IPP these border pixels are considered as "replicated", that may lead to some artifacts in the border area. The "true" deconvolved area is only "valid" area (Matlab notation: image.width-kernel.width+1; image.height-kernel.height+1). You don't need to scale (f32) your image, the meaning of threshold parameter is the same as for Matlab or OpenCV (for example http://onsignalandimageprocessing.blogspot.com/2017/02/lucy-richardson-deconvolution.html ). The place of image is the top-left corner. You also can try ippiFilterWiener for de-blurring purpose.

regards, Igor

Petric__Sinisa
Beginner
143 Views

Hi Igor,

The first error in my code was  kernel construction. I was experimenting with some fixed kernel values and got completely green image (BR channels were 0). So, I've concluded that kernel is actually 1D-array of the form {B0,G0,R0,B1,G1,R1,...}. So kernel should be:

Ipp32f *kernel = new Ipp32f[kernelSize*kernelSize*3];

I still don't know is such kernel construction OK, but it gives reasonable results. Regarding Wiener filter, it works well, but I want to try DeconvLR. I still don't know the range of threshold parameter? Should it be in the range [0,255], or in the range [0, 1]?

Regards, Siniša 

 

Adriaan_van_Os
New Contributor I
143 Views

> The first error in my code was  kernel construction. I was experimenting with some fixed kernel values and got completely green image (BR channels were 0). So, I've concluded that kernel is actually 1D-array of the form {B0,G0,R0,B1,G1,R1,...}.

Is that true ? ?

You could also try ippiDeconvFFT.

Regards,

Adriaan van Os

Reply