Page 1 of 1

Resize using center of pixel (not edge)

Posted: 2011-05-28T09:34:20-07:00
by NicolasRobidoux
Anthony:

I feel quite strongly that in many common situations one should use the "align corner pixel centers" convention when enlarging images.

(Unfortunately I have no time for IM hacking right now.)

Does the following code use the "nice" virtual pixel policy which one, I believe, gets with -distort resize?

I (of course) want to use this with, among other things, Jinc lanczossharp, which is a method that really impressed LGM 2011 conference attendees. (I told them I was using JInc lanczos for simplicity, but they were shown Jinc lanczossharp results.)

(I don't care about speed. Only quality.)
anthony wrote:...
A variation on this (not shown on the page) is to use a two point affine distortion (distorting using the middle of pixels

Code: Select all

  convert \( xc:red xc:blue +append \) \
          \( xc:yellow xc:cyan +append \) -append \
          -filter point -interpolate bilinear -define distort:viewport=100x100 \
          -distort Affine '.5,.5 .5,.5   1.5,1.5 99.5,99.5'       interpolate_bilinear.jpg
...
That is equivalent to the FX method and is faster but as you can see needs some setup.
P.S.

Dear Santa: Could you please give me a -distort resize for which I can choose between the "align corner pixel corners" (current IM default) and the "align corner pixel centers" image alignment conventions (what I want for upsampling)? Even better, could I have the same options with -resize as well?

Re: Create a MultiColor Image

Posted: 2011-05-28T09:56:03-07:00
by fmw42
Nicolas,

You could use -distort Affine with properly chosen control points set to pixel centers. That I believe is one way, though a bit awkward. A script could be created that takes the scale factor and image dimensions and computes the control points.

Alternately and perhaps better, one could make a script to use the desired scale factor along with properly centered control points (from the image dimensions) to compute the relevant scale factor and then use -distort resize

You may be able to set the viewport and use -distort SRT, also, but I have not given that much thought and it might be wrong. Anthony would have to comment.

But I agree and perhaps your suggestion should be added if not already in Anthony's "wish list" for IM 7. It could be chosen perhaps via a -set or -define?

Fred

Perhaps your post and mine should really be moved to another topic.

Re: Create a MultiColor Image

Posted: 2011-05-28T11:45:38-07:00
by NicolasRobidoux
Indeed, once I figure out which of the various methods use the "good" virtual pixel policy (or figure out how to enforce is), I can get what I want all sorts of ways.

However, what I'd like is a "key in hand" solution for people I do consulting work for. That works, e.g., with

Code: Select all

-gravity center
(If I was not so swamped right now...)

Note: The solution does not need to handle transparency perfectly as far as I'm concerned: I can delete the transparency channel first thing.

Re: Create a MultiColor Image

Posted: 2011-05-28T16:07:35-07:00
by fmw42
Try this comparison. I think it might be correct, but will defer to Anthony. The first image is the current corner scaled version and the second is using the corner pixel's center points to compute the scale factors.


scale=4
scalepct=`convert xc: -format "%[fx:100*$scale]" info:`
xscalepct=`convert rose: -ping -format "%[fx:100*($scale*w-1)/(w-1)]" info:`
yscalepct=`convert rose: -ping -format "%[fx:100*($scale*h-1)/(h-1)]" info:`
echo "scalepct=$scalepct; xscalepct=$xscalepct; yscalepct=$yscalepct"
convert rose: -distort resize $scalepct% rose_resize1.png
convert rose: -distort resize ${xscalepct}x${yscalepct}% rose_resize2.png

Re: Create a MultiColor Image

Posted: 2011-05-28T16:23:20-07:00
by NicolasRobidoux
Ah ah!

I had forgotten that IM often uses the center of the input image as control point.

Thank you Fred. (Your code, I believe, does not quite do what I want, but it's progress.)

Re: Create a MultiColor Image

Posted: 2011-05-28T17:23:51-07:00
by NicolasRobidoux
Also:

I understand perfectly that my "Santa" request would require a lot of elfin overtime: -resize has a million geometrical tweaking options, and having them work across the board with a different image size convention may be far from trivial.

Re: Create a MultiColor Image

Posted: 2011-05-28T19:59:35-07:00
by NicolasRobidoux
At this point, I actually don't need something fully general.

I think I'll be able to figure out something workable based on the above advice.

Re: Resize using center of pixel (not edge)

Posted: 2011-05-29T22:03:19-07:00
by anthony
The control points used for the resize (center of edge pixel, to center of new edge pixel) was only one aspect of the command that is under discussion. (Repeated here)

Code: Select all

  convert \( xc:red xc:blue +append \) \
          \( xc:yellow xc:cyan +append \) -append \
          -filter point -interpolate bilinear -define distort:viewport=100x100 \
          -distort Affine '.5,.5 .5,.5   1.5,1.5 99.5,99.5'       interpolate_bilinear.jpg
Image
Note that the scaling is NOT 2 pixels to 100 pixel (x50) but 1 pixel scaled to 99 pixels (x99)
ASIDE: the affine projection matrix is -distort AffineProjection '99 0 0 99 -49 -49'

The other key aspect of the above is the use of a view port to actually trim the excess pixels from the result.
If you did not have that viewport you would still get a image that is essentially 198 pixels wide (plus a little bit for virtual pixel blending). That is to say the viewport is just as important as the scaling.

Because of this you can not just scale the image and get a correct 'edge pixel center resize'.

That actual example in this case is purely returning the area between the pixels. I needed to do the resize in this way as it was this area between pixels that was the important focus in that example. That is the interpolation that is being performed between the pixels when the lookup is a floating point value. It is NOT however what users expect to see when they simply resize images, as they focus on whole pixels, and not the interpolated area.



Now in a actual image resize you would not be using a simple bilinear interpolation, but something that would have a much larger area of influence. In any such larger convolution neighbourhood, you will naturally get virtual pixel effects, as the virtual pixels are less that one pixel away. Even with bi-cubic interpolation (16 neighbours, and a support distance of 2.0) will involve virtual pixel effects in the results, for than and any other 'resize using pixel centers'.

As such you will still need to either set appropriate virtual pixel setting or remove the influence of virtual pixel using the VP transparency technique on the results (see previous topic on creating a distort resize)
viewtopic.php?p=68362#p68362

I hope in IMv7 we will have a switch to completely remove virtual pixel effect from the results, in specific cases. that is remov its effect not only from color channels but the transparency channel too.



I do not see -distort Resize being modified to allow for this type of 'pixel center' resize, though it is quite possible for it to be implemented.

If it is implemented I would prefer to use a special operational name for it (does it have a formal name in the scientific litrature) and have BOTH a orthogonal (tensor) and cylindrical variant implemented.

ASIDE: all interpolations are direct orthogonal filter styles of interpolation. However it is quite possible that some 2D radial interpolators could be added. Not that anyone has ever requested them. I would like to see the hermite filter added as a interpolator :-)