Re: About your Transform Perspective Plugin for ImageJ

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Re: About your Transform Perspective Plugin for ImageJ

Stephan Saalfeld
Hi Gautam Shankar,

I do not think that you can do that with a macro, but it's easy to
access the underlying library from any JVM connected scripting language
like Javascript, Jython, BeanShell or others (in Fiji,
Pugins->Scripting->... Interpreter).  Here the code in my preferred
language BeanShell:

/* import more than we need */
import ij.*;
import ij.process.*;
import mpicbg.models.*;
import mpicbg.ij.*;
import mpicbg.util.*;
import java.util.*;

/* just for testing, open an image */
IJ.run("Clown (14K)");

/* source coordinates */
p1 = new Point( new float[]{ 0.0f, 0.0f } );
p2 = new Point( new float[]{ 100.0f, 0.0f } );
p3 = new Point( new float[]{ 0.0f, 100.0f } );
p4 = new Point( new float[]{ 100.0f, 100.0f } );

/* target coordinates */
q1 = new Point( new float[]{ 10.0f, 5.0f } );
q2 = new Point( new float[]{ 90.0f, 10.0f } );
q3 = new Point( new float[]{ -10.0f, 110.0f } );
q4 = new Point( new float[]{ 110.0f, 95.0f } );

/* associate source and target coordinates */
m = new ArrayList();
m.add( new PointMatch( p1, q1 ) );
m.add( new PointMatch( p2, q2 ) );
m.add( new PointMatch( p3, q3 ) );
m.add( new PointMatch( p4, q4 ) );

/* instantiate perspective model and fit to points */
h = new HomographyModel2D();
h.fit( m );

/* use perspective model to render a transformed image */
mapping = new InverseTransformMapping( h );
src = IJ.getImage().getProcessor();
dst = src.createProcessor( src.getWidth(), src.getHeight() );
mapping.mapInterpolated( src, dst );
new ImagePlus( IJ.getImage().getTitle() + " transformed", dst ).show();

/* up to here, we have the perspectively transformed image rendered
just like in the interactive plugin, but now we'd like to see the full
image and not just a crop */

/* use the perspective model to estimate the bounding box */
/* instantiate image corner coordinates */
tl = new float[]{ 0, 0 };
tr = new float[]{ src.getWidth() - 1, 0 };
bl = new float[]{ 0, src.getHeight() - 1 };
br = new float[]{ src.getWidth() - 1, src.getHeight() - 1 };

/* transfer corner coordinates */
h.applyInPlace( tl );
h.applyInPlace( tr );
h.applyInPlace( bl );
h.applyInPlace( br );

/* get minimal and maximal transferred coordinates */
minX = Math.min( tl[ 0 ], Math.min( tr[ 0 ], Math.min( bl[ 0 ], br[ 0 ] ) ) );
minY = Math.min( tl[ 1 ], Math.min( tr[ 1 ], Math.min( bl[ 1 ], br[ 1 ] ) ) );
maxX = Math.max( tl[ 0 ], Math.max( tr[ 0 ], Math.max( bl[ 0 ], br[ 0 ] ) ) );
maxY = Math.max( tl[ 1 ], Math.max( tr[ 1 ], Math.max( bl[ 1 ], br[ 1 ] ) ) );

/* compensate for the translational offset of the bounding box */
t = new TranslationModel2D();
t.set( -minX, -minY );
l = new InverseCoordinateTransformList();
l.add( h );
l.add( t );
mapping = new InverseTransformMapping( l );
dstBoxed = src.createProcessor(
        ( int )Math.ceil( maxX - minX ),
        ( int )Math.ceil( maxY - minY ) );
mapping.mapInterpolated( src, dstBoxed );
new ImagePlus( IJ.getImage().getTitle() + " transformed boxed", dstBoxed ).show();


I hope that helps to understand the basics of the mpicbg transformation
library.

Best regards,
Stephan


On Mon, 2010-06-28 at 09:31 -0700, GAUTAM SHANKAR wrote:

> Hi Stephan,
>
> I'm trying to use your plugin to automate perspective correction for
> my images. Since, your plugin uses 4 control points,
> I'd like to write a script to move those points to whatever
> coordinates.
>
> http://pacific.mpi-cbg.de/cgi-bin/gitweb.cgi?p=mpicbg.git;a=blob;f=mpicbg/ij/InteractiveInvertibleCoordinateTransform.java;h=23b3a236718a70e1ec49b712e05e30fca4363d9f;hb=HEAD
>
> Can you tell me how I can write a macro that inputs new coordinates
> for each of those control points? Any help is much appreciated.
>
>
> -Gautam Shankar