vnt

Class Lighting_Correction

Implemented Interfaces:
PlugInFilter

public class Lighting_Correction
extends VascularNetworkToolkit
implements PlugInFilter

This plug-in is meant to be used for images with a no-reducing lense. Any images with a single centered light should use this.

Accepts a grayscale image as input and fits an n-th order polynomial surface by treating color as a z value. The fit surface is used to adjust lighting irregularities accordingly.

This class relies on JAMA, a public domain Java Matrix package for all least-squares regression matrix calculations, freely available at http://math.nist.gov/javanumerics/jama/.

Version:
1.0
Author:
Michael Miller - Truman State University
Since:
1.0

Field Summary

private double[]
coefficients
The array that stores the terms for the function f(x,y).
private int
order
The 'n' order of the polynomial surface.
private int
orderTerms
The number of terms for the given polynomial surface.

Method Summary

void
calculateSurfaceCoefficients(ImageProcessor bp)
Based on the order, this method goes through the entire process of calculating an A, b, and p matrix

Pre: The setDegree() method was called and
Post: The local member coefficients is initialized and prepared for use.

boolean
drawCorrectedImage(ImageProcessor bp)
Draws the light-corrected image onto a newly created image.
boolean
drawSurface()
Draws the approximated surface onto a newly created image.
private int
getCutoffViaHistographThreshold(ImageProcessor bp)
Analyzes the histograph for the most common colors.
private Jama.Matrix
getLeastSquaresProjection(Jama.Matrix A, Jama.Matrix b)
Performs a least-squares regression.
private int
polynomialSurface(double x, double y)
Returns the function value of the polynomial surface at the coordinate (x,y) given the surface function f(x,y) = a + b*x + c*y + d*x^2 + ...
void
run(ImageProcessor bp)
The executed method when the plug-in is successfully called.
int
setDegree(int degree)
Initializes the local order information for the least-squares fit.
int
setup(String arg, ImagePlus ip)
Specifies the preconditions for the plug-in.

Field Details

coefficients

private double[] coefficients
The array that stores the terms for the function f(x,y). Ex: If order = 3, then the surface is given to be f(x,y) = a + b*x + c*y + d*x^2 + e*x*y + f*y^2 + g*x^3 + h*x*y^2 + i*x^2*y + j*y^3 Here, coefficients[0] == a, coefficients[7] == h, etc.

order

private int order
The 'n' order of the polynomial surface. Also read as degree.

orderTerms

private int orderTerms
The number of terms for the given polynomial surface. orderTerms = ((order+1)*(order+1)+(order+1))/2; Ex: If order = 3, then the surface is given to be f(x,y) = a + b*x + c*y + d*x^2 + e*x*y + f*y^2 + g*x^3 + h*x*y^2 + i*x^2*y + j*y^3 Here orderTerms is 10, or given by the equation [(order+1)*(order+1)+(order+1)]/2 = 10

Method Details

calculateSurfaceCoefficients

public void calculateSurfaceCoefficients(ImageProcessor bp)
Based on the order, this method goes through the entire process of calculating an A, b, and p matrix

Pre: The setDegree() method was called and
Post: The local member coefficients is initialized and prepared for use. The surface has been approximated.

Parameters:
bp - The imageProcessor for the original 8-bit grayscale image.

drawCorrectedImage

public boolean drawCorrectedImage(ImageProcessor bp)
Draws the light-corrected image onto a newly created image.

Pre: The fit has already been performed. This requires the members order and orderTerms to be initialized. The passed double[] array must be the solution to the regression.
Post: A new image is created and displayed.

Parameters:
bp - The Image Processor for the original grayscale image.
Returns:
Returns true on successful image creation and drawing. False otherwise.

drawSurface

public boolean drawSurface()
Draws the approximated surface onto a newly created image.

Pre: The fit has already been performed. This requires the members order and orderTerms to be initialized. The passed double[] array must be the solution to the regression.
Post: A new image is created and displayed.

Returns:
Returns true on successful image creation and drawing. False otherwise.

getCutoffViaHistographThreshold

private int getCutoffViaHistographThreshold(ImageProcessor bp)
Analyzes the histograph for the most common colors. I'm thinking I'll do an epsilon-neighborhood thing on the colors and see which is the largest. Then I'll set that color (or that color+epsilon radius) to be the threshold cutoff. Why do this? My motivation is I have all these images with black borders. Surface Plot 3D gives a really nice quadratic surface except where it hits the bottom 0 value. This is to stop those data points from damaging the quality of the least-squares fit later.

Pre: The ImageProcessor is a grayscale image.
Post: The method returns a computed threshold for pixels to be considered for lighting correction.

Parameters:
bp - The ImageProcessor for the image to allow for access to the histograph information.
Returns:
Returns the value to ignore. Such that all colors of 0 to (that value) will be ignored for least-squares fitting.

getLeastSquaresProjection

private Jama.Matrix getLeastSquaresProjection(Jama.Matrix A,
                                              Jama.Matrix b)
Performs a least-squares regression. This will return a matrix of the size (columns of A, 1). Solves for the solution by the formula: p = (A^T * A)^-1 * A^T * b. Where A , b is the function value at those datapoints, and p is the desired projection vector that is the closest fit.

Pre: Assumes matrix A and B are properly formed and of appropriate dimension.
Post: Returns the projection matrix (the solution) of the least-squares regression for matrices A and b.

Parameters:
A - The matrix of datapoints. Each row should be of the form x*x,x*y,y*y,1
b - The matrix of function (color) values.
Returns:
Returns a matrix (columns of A)x1 matrix that represent the constant values of the best fit projection.

polynomialSurface

private int polynomialSurface(double x,
                              double y)
Returns the function value of the polynomial surface at the coordinate (x,y) given the surface function f(x,y) = a + b*x + c*y + d*x^2 + ... The polynomial surface is n-th order, where 'n' is the member variable 'order.' The number of terms in the function is defined by orderTerms

Pre: The given double[] eq array is not null.
Post: The method returns the function value f(x,y) is returned as defined by the coefficients in eq.

Parameters:
x - The x coordinate of the function.
y - The y coordinate of the function.
Returns:
Returns the result of the function f(x,y).

run

public void run(ImageProcessor bp)
The executed method when the plug-in is successfully called. 1) Performs a n'th order polynomial surface least-squares fit on the original image. 2) Creates a new image and displays the polynomial surface fit. 3) Copies the old image onto a second new image with light-corrected values.

Pre: The image was cleared to run by the setup() method.
Post: The image is processed by the lighting correction routines. A new corrected image is drawn.

Parameters:
bp - Required by the interface. The access information to the original image.

setDegree

public int setDegree(int degree)
Initializes the local order information for the least-squares fit. Calculates the number of terms the n-th order polynomial surface equation has.

Pre: Assumes degree is a non-negative integer. If a negative order is passed, the order is calculated to be 0.
Post: The order and orderTerms local members are initialized. The fit is ready to be calculated.

Parameters:
degree - The desired maximal order for the polynomial surface.
Returns:
Returns the set order of polynomial surface.

setup

public int setup(String arg,
                 ImagePlus ip)
Specifies the preconditions for the plug-in. If this method succeeds then run() is called.

Pre: ImageJ is running and an 8-bit grayscale image is open. The plug-in was just activated.
Post: Either an argument was processed, the image was not saved to a local folder, or the plug-in is cleared to run on the image.

Parameters:
arg - Required by the interface. The argument list passed to the plug-in.
Returns:
If DONE is returned, ImageJ quits without run()'ing the plug-in. Otherwise, the plug-in signals to ImageJ that this plugin only handles 8-bit (256 grayscale) and will not change the original image.