I've made bicubic interpolation which is referring here But I found a quite a bit difference between GIMP's and my own code's result. This is original image
As you can see the above 2 images (A) is Gimp's (B) is my own code with referring.
I confused that did I something wrong? Should I change the algorithm?
Would you please give any advice?
You are downsampling, not upsampling. Interpolation by itself works great when upsampling (increasing the number of pixels).
When downsampling, either with our without interpolation, you're throwing away information, and you get aliasing. This is the effect you see in your result.
Gimp, when downsampling, smooths the image first. The smoothing removes higher frequencies that would be aliased otherwise.
To get similar results to Gimp's, apply a low-pass filter before downsampling.
Here is an example of downsampling with and without low-pass filtering. I'm using MATLAB with DIPimage because it's easy for me and you didn't specify a programming language. It is just to illustrate the principle anyway.
I'm straight-on downsampling with an integer factor here, you already have code to do the same with a non-integer factor, I don't want that to be a distraction here.
s1
is simply downsampling, without smoothing. It looks like your result. This is aliasing.
s2
and s3
use Gaussian low-pass filters of different sizes. I used sigmas of 8*0.5
and 8*0.8
here. After downsampling, these correspond to sigmas of 0.5 and 0.8, respectively. The first one is slightly too small, it still shows some aliasing, but a lot less. It is also still sharp. The second one is the right size to prevent aliasing (less than 1% of the energy or so is aliased).
s4
uses ideal low-pass filtering (in the Fourier domain). I don't recommend this method, because it leads to a lot of ringing. It is just here for comparison. There is 0% aliasing in the output, and the result is as sharp as it can possibly be at this size.
a = readim('https://i.sstatic.net/1TyGI.jpg');
a = a{1};
f = 8; % subsample by a factor 8
s1 = a(0:f:end,0:f:end);
s2 = gaussf(a,f*0.5);
s2 = s2(0:f:end,0:f:end);
s3 = gaussf(a,f*0.8);
s3 = s3(0:f:end,0:f:end);
s4 = ft(a);
s4 = cut(s4,imsize(s1));
s4 = real(ift(s4) / numel(a) * numel(s4));