Page 1 of 2

Perspective + Shepards -- feature request

Posted: 2014-07-18T04:53:40-07:00
by Marcin
Dear MagickWand wizards,

Here is my use case: I am developing a batch application for generating high-quality stylized sky maps. To this end, I overlap distorted images of constellations and exactly positioned stars. Here is an example:
Image
PerspectiveDistortion maps the points of my source Ursa Major image with labels 1-4 to their exact target positions. I know this from Hevelius’ original drawing:
Image

Since PerspectiveDistortion is only an approximation of a spherical projection and since Hevelius took some liberties with star positions, other points of the image might not be mapped where they should. For instance, Ursa’s tail should pass through Alioth and her right rear leg should include Tania Australis (see both images above). Fixing these imperfections looks like a perfect job for ShepardsDistortion but I can’t figure out how to compute its source coordinates after a PerspectiveDistortion with dynamic coefficients. Without PerspectiveDistortion, ShepardsDistortion only makes a swirly mess out of Ursa since it is more of a displacement than a distortion. PolynomialDistortion produces bad results, too: the required local moves have global effects, which makes the resulting Ursa dissimilar to herself.

I cannot see a viable solution now (am I missing something?). As a humble feature request for future releases, I can see two ways:
1. Either expose the coefficients computed internally by PerspectiveDistortion so that one can proceed in three steps: apply PerspectiveDistortion, calculate the coordinates of one's control points after it, pass them as source coordinates to ShepardsDistortion.
2. Or expose a combined Perspective + Shepards distortion. The first step would map the control points close to their final positions by the least squares fit, the second step would perform local adjustments.

Cheers,
Marcin

Re: Perspective + Shepards -- feature request

Posted: 2014-07-18T06:56:56-07:00
by snibgo
I can't help with MagickWand aspects.

From the command line, "-verbose -distort Perspctive" gives both forwards and reverse parameters. You can then manually calculate the destination of any source, or the source of any destination. Does this help?

Re: Perspective + Shepards -- feature request

Posted: 2014-07-18T08:40:14-07:00
by Marcin
Thank you, snibgo. I did consider the way you propose. My C++ program would have to spawn 'convert' on each constellation image, read its stderr through a pipe, parse the coefficients, read the converted image from the disk, and pass it on to ShepardsDistortion. All in all, this would be an ugly hack around the lack of an API for accessing the calculated coefficients of PerspectiveDistortion. If my feature request is rejected, I can follow this path, but since my (to be open-sourced) application is not an urgent matter, I would prefer a cleaner way.

Thanks,
Marcin

Re: Perspective + Shepards -- feature request

Posted: 2014-07-18T09:29:02-07:00
by snibgo
Ah, I understand. Your request is for an API that can pass back the stderr output from verbose distort. That sounds like a reasonable request (but I have no idea about how easy it would be).

Re: Perspective + Shepards -- feature request

Posted: 2014-07-18T10:33:54-07:00
by dlemstra
What are the commands you are executing on the command line?

Re: Perspective + Shepards -- feature request

Posted: 2014-07-18T11:02:58-07:00
by fmw42
I think there is likely information internal to the perspective distortion when you use more than 4 points. It does a least square fit of some kind and thus must have some residuals or could be coded to produce them. Anthony would know more about that.

Re: Perspective + Shepards -- feature request

Posted: 2014-07-19T00:24:34-07:00
by Marcin
dlemstra wrote:What are the commands you are executing on the command line?
None. I'm using the MagickWand API, not the command-line tools. Apologies if that wasn't clear.

Re: Perspective + Shepards -- feature request

Posted: 2014-07-19T10:06:04-07:00
by fmw42
You could try a second or third order polynomial distort. However, it can "extrude" at odd places if not enough control points are picked. See http://www.imagemagick.org/Usage/distorts/#polynomial

Re: Perspective + Shepards -- feature request

Posted: 2014-07-19T10:35:33-07:00
by Marcin
I tried quadratic distort with 8 control points. The result is grotesque, like I warned in the first post:
Image

Re: Perspective + Shepards -- feature request

Posted: 2014-07-19T10:42:52-07:00
by fmw42
That is why you need many points >> 8. And try to get control points near the corners and sides to keep it from extruding.

Re: Perspective + Shepards -- feature request

Posted: 2014-07-19T11:17:49-07:00
by Marcin
fmw42 wrote:That is why you need many points >> 8. And try to get control points near the corners and sides to keep it from extruding.
Sure. But in fact, in Ursa Major only these 8 points need to be fixed. I'd prefer to avoid picking dozens of points for dozens of constellations by hand just to fight with the shortcomings of PolynomialDistortion.

Re: Perspective + Shepards -- feature request

Posted: 2014-07-19T11:21:43-07:00
by fmw42
OK. I understand.

Re: Perspective + Shepards -- feature request

Posted: 2014-07-20T20:47:00-07:00
by anthony
Perspective distortion is straight forward. and mapping specific coordinates in either direction is also quite straight forward. Examples of doing this is in Layering Images

Layering Images, Positioning Distorted Perspective Images
http://www.imagemagick.org/Usage/layers/#layer_distort

However Shepard's Distortion while free form, is only one direction.

Essentually it internally creates a displacement map using a Shepard's Interpolation, for X and Y coordinates.
See Shepard's Gradient, from "Sparse Points of Color"
http://www.imagemagick.org/Usage/canvas/#shepards

Basically the X and Y displacement of each control point generates the 'points' in "Sparse Points of Color", to generate Displacement Maps. This however is done internally for each destination coordinate, rather than specifically creating a displacement map image.

Unfortunatally that distortion is really a one way transformation. There is no 'reverse' or 'forward mapped' form to the distortion. That make attempting to calculate where a specific point in the source image will end up in the destination image, a imposibility without using some type of repeated 'trial and error' method get a better result.

Also as you noted you get 'swirling' effects, as the distortion also trys to preserve the image rotation around control points, not just its position.

What you probably want is some kind of 'piece-wise' distortion (qrid or trianglar) perhaps with a smoothing spline patches. That is each area between 'control points' is handled by a distortion using different coefficents. However the current programming of the IM distort functions was not really designed with piece-wise distortions in mind, only a global single distortion of the whole image, and would take a re-write (to add better internal distort data-structures) to implement it.

Re: Perspective + Shepards -- feature request

Posted: 2014-07-20T20:57:48-07:00
by Marcin
anthony wrote:Perspective distortion is straight forward. and mapping specific coordinates in either direction is also quite straight forward. Examples of doing this is in Layering Images

Layering Images, Positioning Distorted Perspective Images
http://www.imagemagick.org/Usage/layers/#layer_distort
Thank you for taking the time to answer my question, Anthony. Using this method is basically what I outlined in my second post -- it just looks unwieldy to me to spawn a subprocess in order to get the coefficients. I was asking for a programmatic way to access them in MagickWand.

Re: Perspective + Shepards -- feature request

Posted: 2014-07-20T21:16:56-07:00
by fmw42
I do not know if this will help, but you could do a mesh warp. see my script at http://www.fmwconcepts.com/imagemagick/ ... /index.php for an example.