Recent

Author Topic: Strange behavior BGRABitmap.PutImageAngle  (Read 1206 times)

stab

  • Full Member
  • ***
  • Posts: 182
Strange behavior BGRABitmap.PutImageAngle
« on: March 19, 2019, 05:39:58 pm »
Hi,

When testing BGRABitmap.PutImageAngle I noticed a peculiarity that
seem to be related to colorvalues that are multiples of 256.

To make a real test I made 2 images, both with only 2 colorvalues.
One with colorvalues 200 and 300 and the other with colorvalues 300 and 400.

Attached are
the original images(img_200_300.png and img_300_400.img),
the corresponding rotated images(img_200_300_rotated.png and img_300_400_rotated.png),
the rotated images in 3D(img3D_200_300.png and img3D_300_400.png) and
profiles over a part of the rotated images(profile_200_300.png and profile_300_400.png).


Code used as follows:
Code: Pascal  [Select]
  1. procedure TfrmRotateModel.btnVridBildClick(Sender: TObject);
  2. var
  3.   bmp, bmprotate : TBGRABitmap;
  4.   temp : string;
  5. begin
  6.   if not OpenPictureDialog1.Execute then Exit;
  7.  
  8.   bmp := TBGRABitmap.Create(OpenPictureDialog1.FileName);
  9.   bmprotate := TBGRABitmap.Create(4 * bmp.Width, 4 * bmp.Height, clWhite);
  10.   try
  11.     bmprotate.PutImageAngle(0.75 * bmp.Width, 1.5 * bmp.Height, bmp,
  12.     0, bmp.Width div 2, bmp.Height div 2);
  13.     bmprotate.InvalidateBitmap;
  14.     temp := OpenPictureDialog1.FileName;
  15.     temp := ChangeFileExt(temp, '');
  16.     bmprotate.SaveToFile(temp + '_rotated.png');
  17.   finally
  18.     FreeAndNil(bmp);
  19.     FreeAndNil(bmprotate);
  20.   end;
  21. end;          

As seen from the code, rotation angle is zero, but PutImageAngle is executing
some code that gives the strange result at colorvalue 256.
In image: img3D_200_300.png one can see some extrem values when colors
change from 200 to 300. That is also seen in profile: profile_200_300.png.
That behavior is not seen in img3D_300_400.png and the corresponding profile.

Can someone explain what is going on and how to get rid of these odds? %)

Maybe I'm using PutImageAngle in a wrong way, please tell me if you find
any mistake on my part.

/stab

Windows 10 64 bit
Lazarus version: 1.8.4
FPC version: 3.0.4
SVN Rev: 57972
« Last Edit: March 19, 2019, 05:46:23 pm by stab »

circular

  • Hero Member
  • *****
  • Posts: 3053
    • Personal webpage
Re: Strange behavior BGRABitmap.PutImageAngle
« Reply #1 on: March 19, 2019, 11:27:15 pm »
Not sure what you mean by colorvalues multiples of 256.

Though I see that the image is stretched by one pixel and thus blurred a bit.
Conscience is the debugger of the mind

stab

  • Full Member
  • ***
  • Posts: 182
Re: Strange behavior BGRABitmap.PutImageAngle
« Reply #2 on: March 19, 2019, 11:39:20 pm »
What I mean is that you get a strange effect when you have colorvalues in an image that are some multiple of 256. That is why I sent 2 different images, one with value range 200-300, where one can see the effect. The other image is in range 300-400 and there the image is not effected when rotated.
I don't know if one really can call the result blur, as it is only effecting one of the images

circular

  • Hero Member
  • *****
  • Posts: 3053
    • Personal webpage
Re: Strange behavior BGRABitmap.PutImageAngle
« Reply #3 on: March 19, 2019, 11:44:47 pm »
Still not getting what is the value range you're talking about. Is it the red channel?
In img_200_300.png it goes from 44 to 200.
And in img_300_400.png it goes from 44 to 144.
Conscience is the debugger of the mind

stab

  • Full Member
  • ***
  • Posts: 182
Re: Strange behavior BGRABitmap.PutImageAngle
« Reply #4 on: March 20, 2019, 07:32:27 am »
As I see it, things are like this:
img_200_300.png and img_300_400.png have just 2 unique colors each.
img_200_300.png:
 color1: 200 (red=200, green=0,  blue=0)
 color2: 300 (red=44,  green=1,  blue=0)
img_300_400.png:
 color1: 300 (red=44,  green=1,  blue=0)
 color2: 400 (red=144, green=1,  blue=0)
 
When you rotate an image in PutImageAngle there are extra colors added
where the color shifts because of antialiasing.
img_200_300_rotated.png has 140 unique colors and
img_300_400_rotated.png has 99 unique colors.

When img_200_300.png is rotated(in this case 0 degrees) you get a
strange effect where the color shifts from 200 to 300 i.e when red byte
reaches 255 because of antialiasing at the color shift border.
In img_300_400.png you don't get this effect because red byte
doesn't reach 255.

This same effect I have noticed also for color shifts from 500 to 600
i.e at 512 and so on.

I'm actually using BGRABitmap to rotate a DEM and the result is very good
except for these oddities. The resulting rotated DEM gets kind of
elevation curves at 255, 512, 768 etc.
I tried to illustrate this in the profiles where one can see a very smooth
curve in profile_300_400.png but not in profile_200_300.png. That can also
be seen in the 3D views.

Perhaps I'm understanding this wrong. Is it possible to affect antialiasing
in some way to circumvent the problem?

Regards
stab
« Last Edit: March 20, 2019, 07:35:39 am by stab »

circular

  • Hero Member
  • *****
  • Posts: 3053
    • Personal webpage
Re: Strange behavior BGRABitmap.PutImageAngle
« Reply #5 on: March 21, 2019, 11:09:09 pm »
I tested with latest version BGRABitmap and I don't get the stretching of 1 pixel so no antialiasing sideeffect. Which version of BGRABitmap are you using?

I think I got what you're saying with color value. You are using red/green/blue to encode the number: red + green*256 + blue*65536. In this case, antialising is not compatible. Indeed, the average of (0,1,0) and (0,0,0) will be either (0,1,0) or (0,0,0) depending on rounding but in your system you would expect (128,0,0) which does not happen because each channel is computed separately. This behavior cannot be overriden. Maybe in some future version of BGRABitmap you will be able to use another colorspace here, but that's not in a near future.

You can affect antialiasing by setting the resample filter (optional parameter after angle of PutImageAngle). Setting to rfBox removes any antialiasing which will avoid the problem.

If you want to compute an antialising that makes sense with your system, I would suggest to draw everything at a bigger scale, for example twice as big and then compute by yourself the average of each four-pixels square.
Conscience is the debugger of the mind

stab

  • Full Member
  • ***
  • Posts: 182
Re: Strange behavior BGRABitmap.PutImageAngle
« Reply #6 on: March 22, 2019, 09:55:23 am »
Thanks for your info.

Your BGRABitmap lib is excellent!!!

/stab