Posted by
Stephan Saalfeld on
Jun 28, 2010; 7:59pm
URL: http://imagej.273.s1.nabble.com/Re-About-your-Transform-Perspective-Plugin-for-ImageJ-tp3687807.html
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: