Inverse convolution of image

前端 未结 5 827
半阙折子戏
半阙折子戏 2020-12-24 04:33

I have source and result image. I know, that some convolution matrix has been used on source to get result. Can this convolution matrix be computed ? Or at least not exact o

5条回答
  •  伪装坚强ぢ
    2020-12-24 05:09

    I have rewritten @Ilmari Karonen answer to C/C++ using fftw3 for someone, who might find it handy:

    Circular shift function

    template
    void circshift(ty *out, const ty *in, int xdim, int ydim, int xshift, int yshift)
    {
      for (int i =0; i < xdim; i++) 
      {
        int ii = (i + xshift) % xdim;
        for (int j = 0; j < ydim; j++) 
        {
          int jj = (j + yshift) % ydim;
          out[ii * ydim + jj] = in[i * ydim + j];
        }
      }
    }
    

    Now main code

    int width = 256;
    int height = 256;
    
    int index = 0;
    
    MyStringAnsi imageName1 = "C://ka4ag.png";    
    MyStringAnsi imageName2 = "C://KyPu2.png";
    
    double * in1 = new double[width * height];
    fftw_complex * out1 = new fftw_complex[width * height]; 
    
    double * in2 = new double[width * height];
    fftw_complex * out2 = new fftw_complex[width * height]; 
    
    MyUtils::MyImage * im1 = MyUtils::MyImage::Load(imageName1, MyUtils::MyImage::PNG);
    MyUtils::MyImage * im2 = MyUtils::MyImage::Load(imageName2, MyUtils::MyImage::PNG);
    
    for (int i = 0; i < width * height; i++)
    {
        in1[i] = ((im1->Get(i).r / (255.0 * 0.5)) - 1.0);
        in2[i] = ((im2->Get(i).r / (255.0 * 0.5)) - 1.0);
    }
    
    
    fftw_plan dft_plan1 = fftw_plan_dft_r2c_2d(width, height, in1, out1, FFTW_ESTIMATE);    
    fftw_execute(dft_plan1);
    fftw_destroy_plan(dft_plan1);
    
    fftw_plan dft_plan2 = fftw_plan_dft_r2c_2d(width, height, in2, out2, FFTW_ESTIMATE);    
    fftw_execute(dft_plan2);
    fftw_destroy_plan(dft_plan2);
    
    fftw_complex * kernel = new fftw_complex[width * height];   
    
    for (int i = 0; i < width * height; i++)
    {
        std::complex c1(out1[i][0], out1[i][1]);
        std::complex c2(out2[i][0], out2[i][1]);
    
        std::complex div = c2 / c1;
    
        kernel[i][0] = div.real();
        kernel[i][1] = div.imag();
    }
    
    double * kernelOut = new double[width * height];
    
    fftw_plan dft_planOut = fftw_plan_dft_c2r_2d(width, height, kernel, kernelOut, FFTW_ESTIMATE);
    fftw_execute(dft_planOut);
    fftw_destroy_plan(dft_planOut);
    
    double * kernelShift = new double[width * height];
    
    circshift(kernelShift, kernelOut, width, height, (width/2), (height/2));
    
    double maxKernel = kernelShift[0];
    for (int i = 0; i < width * height; i++)
    {
        if (maxKernel < kernelShift[i]) maxKernel = kernelShift[i]; 
    }
    
    for (int i = 0; i < width * height; i++)
    {
        kernelShift[i] /= maxKernel; 
    }
    
    uint8 * res = new uint8[width * height];
    for (int i = 0; i < width * height; i++)
    {                   
       res[i] = static_cast((kernelShift[i]+ 1.0) * (255.0 * 0.5));
    }
    
    //now in res is similar result as in @Ilmari Karonen, but shifted by +128
    

    Code has no memory management, so you must clean your memory !

提交回复
热议问题