Class Affine

java.lang.Object
  extended by Affine

public class Affine
extends java.lang.Object

The Affine class does affine transform setup and pixel operations.

 Given 3 landmarks (lm1,lm2,lm3) for the two images, solve 
 the linear transforms for (a,b,c,d,e,f)
     x2= a*x1 + b*y1 +c 
     y2= d*x1 + e*y1 +f
 Then also solve the inverse transform (a0,b0,c0,e0,f0).
 This lets us map pixels at location (x,y) in one image to the
 corresponding location (x',y') in the other image.
 NOTE: it will fail if the landmarks are co-linear.

This work was produced by Peter Lemkin of the National Cancer Institute, an agency of the United States Government. As a work of the United States Government there is no associated copyright. It is offered as open source software under the Mozilla Public License (version 1.1) subject to the limitations noted in the accompanying LEGAL file. This notice must be included with the code. The Flicker Mozilla and Legal files are available on http://open2dprot.sourceforge.net/Flicker

Version:
$Date$ $Revision$
Author:
P. Lemkin (LECB/NCI), G. Thornwall (SAIC), Frederick, MD
See Also:
Flicker Home

Field Summary
 float a
          coeff for x2= a*x + b*y1 + c
 float a0
          inverse coefficient for x2= aO*x1 + bO*y1 + cO
static java.lang.String affine_calcsString
          affine xform calculations
 float b
          coeff for x2= a*x1 + b*y1 + c
 float b0
          inverse coefficient for x2= aO*x1 + bO*y1 + cO
 float c
          coeff for x2= a*x1 + b*y1 + c
 float c0
          inverse coefficient for x2= aO*x1 + bO*y1 + cO
 float d
          coeff for y2= d*x1 + e*y1 + f
 float d0
          inverse coefficient for y2= dO*x1 + eO*y1 + fO
 float e
          coeff for y2= d*x1 + e*y1 + f
 float e0
          inverse coefficient for y2= dO*x1 + eO*y1 + fO
 java.lang.String errMsg
          accumulated error messages
 float f
          coeff for y2= d*x1 + e*y1 + f
 float f0
          inverse coefficient for y2= dO*x1 + eO*y1 + fO
private  Flicker flk
          Global instance
private  int height
          Image height
private  boolean isFlipLMSflag
          flip left and right landmarks after copy to local [FUTURE]
private  boolean isValidLMSflag
          Landmark DB has 3 valid landmarks.
 int lm1
          indices of three landmarks
 int lm2
          indices of three landmarks
 int lm3
          indices of three landmarks
 float minLSQcolinearity1
          LSQ colinearity err for I1 lms wrt I1
 float minLSQcolinearity2
          LSQ colinearity error for I2 lms wrt I2
 float thrColinearity
          threshold for colinearity tests
private  int width
          Image width
private  float x11
           
private  float x12
           
private  float x13
           
private  float x21
           
private  float x22
           
private  float x23
           
private  float y11
           
private  float y12
           
private  float y13
           
private  float y21
           
private  float y22
           
private  float y23
           
 
Constructor Summary
Affine(Flicker flk)
          Affine() - constructor which sets up the global links
 
Method Summary
 boolean calcInverseAffine()
          calcInverseAffine() - compute inverse affine coefficients.
 float colinearityLSQerr(int useImgNbr)
          colinearityLSQerr() - compute colinearity of 3 landmarks as LSQ error.
private  void flipLMS()
          flipLMS() - flip the local copy of the 3 landmarks
 java.lang.String getAffineCalcsString()
           
 float[] getAffineCoef()
          getAffineCoef() - return array with [a,b,c,d,e,f]
 float getAffineMLSQcolinearity(int idx)
          getAffineMLSQcolinearity() - get landmark colinearity.
 float[] getINVAffineCoef()
          getINVAffineCoef() - return array with [aO,bO,cO,dO,eO,fO]
private  java.lang.String getLMstr()
          getLMstr() - return the 3 landmark values for I1 and I2
 void initAffine(float thrColinearity, int width, int height)
          initAffine() - init the affine instance for another transform.
 void initDefaultState()
          initDefaultState() - Initialize affine state to no transform present.
 int mapXYtoAffineIdx(int x, int y)
          mapXYtoAffineIdx() - Compute Affine transform (x',y') idx from f(x,y) where idx is the index of the pixel in the input image to be used for the output image.
 int mapXYtoAffineX(int x, int y)
          mapXYtoAffineX() - Compute Affine transform x' from f(x,y) to be used for the output image.
 int mapXYtoAffineY(int x, int y)
          mapXYtoAffineY() - Compute Affine transform y' from f(x,y) to be used for the output image.
 int mapXYtoInvAffineX(int x, int y)
          mapXYtoInvAffineX() - Compute Inverse Affine transform x'= f(x,y) to be used for the output image.
 int mapXYtoInvAffineY(int x, int y)
          mapXYtoInvAffineY() - Compute Inverse Affine transform y' from f(x,y) to be used for the output image.
 java.lang.String setLMSindexes(int lm1, int lm2, int lm3, boolean isFlipLMSflag)
          setLMSindexes() - set the 3 landmark indexes (lm1,lm2,lm3) into the landmark stack where nLM should be >=3.
 java.lang.String showAffineCalcs()
          showAffineCalcs() - show affine calculations string report.
 java.lang.String showAffineLM(java.lang.String msg)
          showAffineLM() - show affine Landmarks
 java.lang.String solveAffineXform()
          solveAffineXform() - compute the affine transformation for 3 LM of the 3 landmarks and return a dynamically allocated affine object.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

flk

private Flicker flk
Global instance


affine_calcsString

public static java.lang.String affine_calcsString
affine xform calculations


width

private int width
Image width


height

private int height
Image height


a

public float a
coeff for x2= a*x + b*y1 + c


b

public float b
coeff for x2= a*x1 + b*y1 + c


c

public float c
coeff for x2= a*x1 + b*y1 + c


d

public float d
coeff for y2= d*x1 + e*y1 + f


e

public float e
coeff for y2= d*x1 + e*y1 + f


f

public float f
coeff for y2= d*x1 + e*y1 + f


a0

public float a0
inverse coefficient for x2= aO*x1 + bO*y1 + cO


b0

public float b0
inverse coefficient for x2= aO*x1 + bO*y1 + cO


c0

public float c0
inverse coefficient for x2= aO*x1 + bO*y1 + cO


d0

public float d0
inverse coefficient for y2= dO*x1 + eO*y1 + fO


e0

public float e0
inverse coefficient for y2= dO*x1 + eO*y1 + fO


f0

public float f0
inverse coefficient for y2= dO*x1 + eO*y1 + fO


thrColinearity

public float thrColinearity
threshold for colinearity tests


minLSQcolinearity1

public float minLSQcolinearity1
LSQ colinearity err for I1 lms wrt I1


minLSQcolinearity2

public float minLSQcolinearity2
LSQ colinearity error for I2 lms wrt I2


errMsg

public java.lang.String errMsg
accumulated error messages


lm1

public int lm1
indices of three landmarks


lm2

public int lm2
indices of three landmarks


lm3

public int lm3
indices of three landmarks


isFlipLMSflag

private boolean isFlipLMSflag
flip left and right landmarks after copy to local [FUTURE]


isValidLMSflag

private boolean isValidLMSflag
Landmark DB has 3 valid landmarks. This does NOT check if they are co-linear.


x11

private float x11

x12

private float x12

x13

private float x13

y11

private float y11

y12

private float y12

y13

private float y13

x21

private float x21

x22

private float x22

x23

private float x23

y21

private float y21

y22

private float y22

y23

private float y23
Constructor Detail

Affine

public Affine(Flicker flk)
Affine() - constructor which sets up the global links

Parameters:
flk - is main class
Method Detail

initAffine

public void initAffine(float thrColinearity,
                       int width,
                       int height)
initAffine() - init the affine instance for another transform.

Parameters:
thrColinearity - threshold
width - of mapping image
height - of mapping image

initDefaultState

public void initDefaultState()
initDefaultState() - Initialize affine state to no transform present.


getAffineCoef

public final float[] getAffineCoef()
getAffineCoef() - return array with [a,b,c,d,e,f]

Returns:
list of coefficients

getINVAffineCoef

public final float[] getINVAffineCoef()
getINVAffineCoef() - return array with [aO,bO,cO,dO,eO,fO]

Returns:
list of inverse coefficients

getAffineMLSQcolinearity

public final float getAffineMLSQcolinearity(int idx)
getAffineMLSQcolinearity() - get landmark colinearity.

Parameters:
idx - is the landmark set to use (1 or 2)
Returns:
minLSQcolinearity1 or minLSQcolinearity2 if index is 1 or 2.

flipLMS

private void flipLMS()
flipLMS() - flip the local copy of the 3 landmarks


setLMSindexes

public final java.lang.String setLMSindexes(int lm1,
                                            int lm2,
                                            int lm3,
                                            boolean isFlipLMSflag)
setLMSindexes() - set the 3 landmark indexes (lm1,lm2,lm3) into the landmark stack where nLM should be >=3. Check for legality of each landmark index.

Parameters:
lm1 - is 1st landmark to use, LM# are >0
lm2 - is 2nd landmark to use LM# are >0
lm3 - is 3rd landmark to use LM# are >0
Returns:
true if all 3 landmarks exist.

calcInverseAffine

public final boolean calcInverseAffine()
calcInverseAffine() - compute inverse affine coefficients. Must be called after solve forward coefficients.

Returns:
TRUE if succeed.

colinearityLSQerr

public float colinearityLSQerr(int useImgNbr)
colinearityLSQerr() - compute colinearity of 3 landmarks as LSQ error.

Parameters:
useImgNbr - to use (1 or 2)
Returns:
sqrt(min(lsqerr(x), lsqerr(y))/3)

getAffineCalcsString

public java.lang.String getAffineCalcsString()

getLMstr

private java.lang.String getLMstr()
getLMstr() - return the 3 landmark values for I1 and I2

Returns:
string showing landmarks

showAffineLM

public java.lang.String showAffineLM(java.lang.String msg)
showAffineLM() - show affine Landmarks

Returns:
string

solveAffineXform

public final java.lang.String solveAffineXform()
solveAffineXform() - compute the affine transformation for 3 LM of the 3 landmarks and return a dynamically allocated affine object.
 This solves the 2 simultaneous equations for (a,b,c,d,e,f):
        x2= a*x1 + b*y1 + c
        y2= d*x1 + e*y1 + f
 given the three landmarks.   *
 [TODO] - check calculations since coeffients look wierd...

Returns:
"" if succeed, else message that particular image is co-linear.

mapXYtoAffineIdx

public final int mapXYtoAffineIdx(int x,
                                  int y)
mapXYtoAffineIdx() - Compute Affine transform (x',y') idx from f(x,y) where idx is the index of the pixel in the input image to be used for the output image. Note: pixelIdx= (y*width + x).
 This assumes that the coefficients exist.
        x'= a*x + b*y + c,
        y'= d*x + e*y + f,
       idxA= (y'*width + x')
 Then,
  compute gO= inputPixels[idxA]

Parameters:
x - to map
y - to map
Returns:
idxI

mapXYtoInvAffineX

public final int mapXYtoInvAffineX(int x,
                                   int y)
mapXYtoInvAffineX() - Compute Inverse Affine transform x'= f(x,y) to be used for the output image.
 This assumes that the coefficients exist.
        x'= aO*x + bO*y + cO,

Parameters:
x - to map
y - to map

mapXYtoInvAffineY

public final int mapXYtoInvAffineY(int x,
                                   int y)
mapXYtoInvAffineY() - Compute Inverse Affine transform y' from f(x,y) to be used for the output image.
 This assumes that the coefficients exist.
        y'= dO*x + eO*y + fO,

Parameters:
x - to map
y - to map
Returns:
(y')

mapXYtoAffineX

public final int mapXYtoAffineX(int x,
                                int y)
mapXYtoAffineX() - Compute Affine transform x' from f(x,y) to be used for the output image.
 This assumes that the coefficients exist.
        x'= a*x + b*y + c,

Parameters:
x - to map
y - to map
Returns:
(x')

mapXYtoAffineY

public final int mapXYtoAffineY(int x,
                                int y)
mapXYtoAffineY() - Compute Affine transform y' from f(x,y) to be used for the output image.
 This assumes that the coefficients exist.
        y'= d*x + e*y + f,

Parameters:
x - to map
y - to map
Returns:
(y')

showAffineCalcs

public java.lang.String showAffineCalcs()
showAffineCalcs() - show affine calculations string report.

Returns:
string showing Affine calculations