计算机视觉
图像处理

图像重建的二维卷积

“真理本身之所以是真理,就在于它穿透了语言的有限性而将人带入到对真实世界的直观把握中。”

——http://my1510.cn/article.php?id=69054

最近在做sparse coding, 用Bruno Olshausen最原始的方法, 因此却发现了一些背后直感上更接近真理的东西。中间有一步需要通过得到的sparse响应重建输入图像,之前一直是用Matlab for循环直接解决的,但是速度奇慢,于是今天尝试了一下把这一部分加速。

首先考虑的是fft2->ifft2的方法,代码如下(参考了http://www.mathworks.com/matlabcentral/newsreader/author/121671):

  1. % Load image
  2. image = im2double(imread(‘./data/lena.png’));
  3. % image=image(201:240,201:240);
  4. [M N] = size(image);
  5. figure(101),subplot(1,2,1),imshow(image,[]);
  6. % Here filter should be a 7×7 patch
  7. filter = reshape(A(:,2),[7,7]);
  8. % Get the filtered response in fft2
  9. F=fft2(image);
  10. H=fft2(filter,M,N);
  11. G=H.*F;
  12. Gnew= G./H;
  13. gnew=real(ifft2(double(Gnew)));
  14. figure(101),subplot(1,2,2),imshow(gnew,[]);

出来的结果是正常。但由于sparse coding的方法并不是直接利用滤波后响应而是将这个响应离散化并且在时间上积累(可以看成是神经元

的membrane potential随着spike的输入而增高)

我实际implement的code是

  1. % Load image
  2. image = im2double(imread(‘./data/lena.png’));
  3. % image=image(201:240,201:240);
  4. [M N] = size(image);
  5. figure(101),subplot(1,2,1),imshow(image,[]);
  6. % Here filter should be a 7×7 patch
  7. filter = reshape(A(:,2),[7,7]);
  8. % Get the filtered response in fft2
  9. F=fft2(image);
  10. H=fft2(filter,M,N);
  11. G=H.*F;
  12. % for ISTA or LCA algorithm
  13. g=real(ifft2(double(G)));
  14. g=g/10;
  15. g=max(abs(g)-0.01,0).*sign(g);
  16. G=fft2(g);
  17. Gnew= G./H;
  18. gnew=real(ifft2(double(Gnew)));
  19. figure(101),subplot(1,2,2),imshow(gnew,[]);

结果出来的结果就如下图中间一幅所示,与用filter乘以sparse响应重建的有一定差距

图1,原图(左), fft2->ifft2结果(中), sparse coding直接重建结果(右)

所以就不得不用c+mex的方法写了一个2d image的deconvolution 程序,mex文件代码如下:

  1. #include <stdio.h>
  2. #include <math.h>
  3. #include “mex.h”
  4. #define a_IN        prhs[0]     /* sparse coefficient matrix */
  5. #define f_IN        prhs[1]     /* filter matrix*/
  6. #define fb_OUT      plhs[0]     /* reconstructed image */
  7. #define a_(i,n)     a[(i) + (n)*ra]     /* A is L x M */
  8. #define f_(i,n)     f[(i) + (n)*rf]     /* X is L x npats */
  9. #define fb_(i,n)    fb[(i) + (n)*rfb]   /* S is M x npats */
  10. static int ra;          /* row number of a */
  11. static int ca;          /* column number of a */
  12. static int rf;          /* row number of f */
  13. static int cf;          /* column number of f */
  14. static int rfb;         /* row number of fb */
  15. static int cfb;         /* column number of fb */
  16. // const mwSize N_DIM=2;
  17. void mexFunction(int nlhs, mxArray *plhs[],
  18.          int nrhs, const mxArray *prhs[])
  19. {
  20.     if (mxGetNumberOfDimensions(a_IN)!=2 || mxGetNumberOfDimensions(f_IN)!=2){
  21.         mexErrMsgTxt(“Both inputs should be 2D matrix.”);
  22.     }
  23.     double *a, *f, *fb;
  24.     a = mxGetPr(a_IN);
  25.     f = mxGetPr(f_IN);
  26.     ra = (int)mxGetM(a_IN);
  27.     ca = (int)mxGetN(a_IN);
  28.     rf = (int)mxGetM(f_IN);
  29.     cf = (int)mxGetN(f_IN);
  30.     rfb = ra+rf-1;
  31.     cfb = ca+cf-1;
  32.     fb_OUT = mxCreateDoubleMatrix(rfb, cfb, mxREAL);
  33.     fb = mxGetPr(fb_OUT);
  34.     //printf(“a: %d, %dn f: %d, %dn fb: %d, %dn”, ra,ca,rf,cf,rfb,cfb);
  35.     //initialize fb to zero;
  36.     for (int i=0;i<rfb;i++){
  37.         for (int j=0;j<cfb;j++){
  38.             fb_(i,j)=0;
  39.         }
  40.     }
  41.     for (int i=0;i<ra;i++){
  42.         for (int j=0;j<ca;j++){
  43.             if (a_(i,j)!=0){
  44.                 for (int i1=0;i1<rf;i1++){
  45.                     for (int j1=0;j1<cf;j1++){
  46.                         fb_(i+i1,j+j1)+=a_(i,j)*f_(i1,j1);
  47.                     }
  48.                 }
  49.             }
  50.         }
  51.     }
  52. }

把这个文件命名成deconv2.cpp 再在matlab里面mex deconv2.cpp编译一下,就是2d deconvolution函数了。运行速度比原来matlab code提高了1000倍左右

后记:后来发现原来这样implement没有必要,matlab里面conv2就能实现这个功能,只不过要得到正确结果的话要先把filter行列反转一下

转载注明来源:CV视觉网 » 图像重建的二维卷积

分享到:更多 ()
扫描二维码,给作者 打赏
pay_weixinpay_weixin

请选择你看完该文章的感受:

1不错 0超赞 0无聊 0扯淡 0不解 0路过

评论 5

评论前必须登录!