1

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

Difference images

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?

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
start02
  • 53
  • 5
  • Difficult to tell from thumbnail images. Do you have the full scale images (including the source one?) – xenoid Jun 27 '18 at 16:14
  • @xenoid upload size is limited as 2MB. But I can let you know the full code. https://github.com/u24c02/scaler – start02 Jun 27 '18 at 16:59
  • Then find smaller samples :) – xenoid Jun 27 '18 at 17:44
  • I believe the equivalent gimp- ode is in app/paint-funcs/scale-region.c (around line 1055 in the Gimp 2.8 branches). Full source code is [here](https://gitlab.gnome.org/GNOME/gimp). – xenoid Jun 27 '18 at 18:01
  • @xenoid I've updated test.bmp from https://github.com/u24c02/scaler you can see the test.bmp this is the origianl image. – start02 Jun 28 '18 at 01:14

1 Answers1

0

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.stack.imgur.com/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));

the 4 images computed above

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
  • Can't find anything in the code that could be smoothing the image. Experimentally I have often seen moirés/aliasing after a scaling, so if there is smoothing it is not the right one. – xenoid Jun 27 '18 at 16:13
  • @xenoid: given that output, it does do smoothing. I haven't looked at the code, but look for an interpolation kernel that is not a true interpolation kernel, i.e. it doesn't go to zero at integer (input) distances. – Cris Luengo Jun 27 '18 at 16:18
  • Could you let me know what kind of smooth do I need? – start02 Jun 27 '18 at 17:00
  • @CrisLuengo Thanks, I didn't know that smooth effect is a quite bit huge. – start02 Jun 28 '18 at 01:17