Page 1 of 1

unexpected PerspectiveDistortion result

Posted: 2019-12-10T06:57:57-07:00
by dummzeuch
I am using MagickDistortImage trying to correct a trapezoid distortion like this:


(image hand painted, just for demonstration purposes)
The image has 640x480 pixels.

I'm using the following parameters:

Code: Select all

MagickDistortImage(TheWand, PerspectiveDistortion,
  [(0.5, 17.5), (0.5, 9.5), (640.5, 29.5), (639.5, 9.5), (640.5, 413.5), (639.5, 444.5), (0.5, 432.5), (0.5, 444.5)],
  8, MagickFalse);
(round brackets inserted just for grouping the coordinates to improve readabilty, it is simply a flat array of double with 16 entries (8 coordinate pairs))

The source coordinates specify the red lines on the next picture, the destination coordinates the blue lines. Both use the full width of the image but only part of the height. So source is a trapezoid and destination is a rectangle.


The result is this:

At first glance, it looks fine, but if you look closer, you will see that not just "horizontal" lines have been corrected but also the vertical lines have been moved.

I didn't expect that. Am I doing anything wrong?

Re: unexpected PerspectiveDistortion result

Posted: 2019-12-10T10:08:30-07:00
by snibgo
You specify some movement in the x-direction, from 640.5 to 639.5. But most of the movement in that direction comes from the expansion in the y-direction.

Perhaps you don't understand perspective distortions. Imagine this wasn't an invented image, but a photo of a fence, with vertical posts and horizontal bars. But the camera is at an angle so the horizontal bars converge towards the right. A perspective correction would have the same effect as straightening the camera angle, making the sensor parallel to the fence. This will make the bars horizontal, but will also move the vertical posts. This is because the posts on the right side were more distant from the camera so were closer together in the photo, and straightening the photo will move those posts apart.

Re: unexpected PerspectiveDistortion result

Posted: 2019-12-11T01:40:06-07:00
by dummzeuch
OK, so I first, I have got a bug here: I move everything by one pixel. (Why didn't I see that when I copyied the parameters? :-(( )

And perspective distortion has a slightly different effect than I thought. Hm, I'll have to think about this some more, whether this is what I need.

Thanks a lot.

Re: unexpected PerspectiveDistortion result

Posted: 2019-12-11T08:02:37-07:00
by snibgo
I'm not sure what you want to do, but let's suppose you want to pin the points near the left corners, move the point near top-right up, and the point near bottom-right down, with no horizontal movement.

One method for this uses displacement maps. An "identity absolute displacement map" causes no movement. It is a horizontal gradient in the R channel (which controls horizontal movement) and a vertical gradient in the G channel (which controls vertical movement).

We can make an identity absolute displacement map, and apply your perspective transformation to distort the map. We could apply the resulting map to your original image to give it the full perspective distortion.

However, we can save the R channel of the identity absolute displacement map before distorting it, and restore that channel after the distortion.

The resulting map then creates no horizontal distortion, and we can apply it to your original image.

Windows BAT syntax. This needs IM v7. If you don't have HDRI, the result will be disappointing unless you use supersampling.

Code: Select all

set PNTS=^

magick ^
  inputPersp.jpg ^
  ( +clone ^
    -sparse-color bilinear ^
%%[fx:w-1],%%[fx:h-1],#ff0 ^
    ( +clone ^
      -channel R -separate +channel ^
      +write mpr:RCHAN ^
      +delete ^
    ) ^
    -distort Perspective "%PNTS%" ^
    -separate ^
    mpr:RCHAN ^
    -swap 0,3 ^
    +delete ^
    -combine ^
  ) ^
  -compose Distort -composite ^