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
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 !