org.opensourcephysics.media.core
Class TemplateMatcher

java.lang.Object
  extended by org.opensourcephysics.media.core.TemplateMatcher

public class TemplateMatcher
extends java.lang.Object

A class to find the best match of a template image in a target image. The match location is estimated to sub-pixel accuracy by assuming the distribution of match scores near a peak is Gaussian.

Version:
1.0
Author:
Douglas Brown

Constructor Summary
TemplateMatcher(java.awt.image.BufferedImage image, java.awt.Shape maskShape)
          Constructs a TemplateMatcher object.
 
Method Summary
 java.awt.image.BufferedImage buildTemplate(java.awt.image.BufferedImage image, int alphaInput, int alphaOriginal)
          Builds the template from an input image.
static int getAlpha(int value)
          Method to get the alpha component from a color value
 int[] getAlphas()
          Gets the alphas used to build the most recent template.
static int getBlue(int value)
          Method to get the blue component from a color value
static int getGreen(int value)
          Method to get the green component from a color value
 int getIndex()
          Gets the index.
 java.awt.image.BufferedImage getMatchImage()
          Gets the most recent match image.
 TPoint getMatchLocation(java.awt.image.BufferedImage target, java.awt.Rectangle searchRect)
          Gets the template location at which the best match occurs in a rectangle.
 TPoint getMatchLocation(java.awt.image.BufferedImage target, java.awt.Rectangle searchRect, double x0, double y0, double theta, int spread)
          Gets the template location at which the best match occurs in a rectangle and along a line.
 double[] getMatchWidthAndHeight()
          Returns the width and height of the peak for the most recent match.
static int getRed(int value)
          Method to get the red component from a color value
 java.util.ArrayList<java.awt.geom.Point2D> getSearchPoints(java.awt.Rectangle searchRect, double x0, double y0, double theta)
          Gets a list of Point2D objects that lie within pixels in a rectangle and along a line.
 java.awt.image.BufferedImage getTemplate()
          Gets the template.
static int getValue(int a, int argb)
          Method to get the color value
static int getValue(int a, int r, int g, int b)
          Method to get the color value
 int[] getWorkingPixels(int[] pixels)
          Gets the working image pixels used to generate the template.
 void setIndex(int index)
          Sets the index.
 void setTemplate(java.awt.image.BufferedImage image)
          Sets the template to be used for the next search.
 void setWorkingPixels(int[] pixels)
          Sets the working image pixels used to generate the template.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

TemplateMatcher

public TemplateMatcher(java.awt.image.BufferedImage image,
                       java.awt.Shape maskShape)
Constructs a TemplateMatcher object. If a mask shape is specified, then only pixels that are entirely inside the mask are included in the template.

Parameters:
image - the image to match
maskShape - a shape to define inside pixels (may be null)
Method Detail

setTemplate

public void setTemplate(java.awt.image.BufferedImage image)
Sets the template to be used for the next search. The new template dimensions must match those of the previous template.

Parameters:
image - the template image

getTemplate

public java.awt.image.BufferedImage getTemplate()
Gets the template. Includes only pixels inside the mask.

Returns:
the template

buildTemplate

public java.awt.image.BufferedImage buildTemplate(java.awt.image.BufferedImage image,
                                                  int alphaInput,
                                                  int alphaOriginal)
Builds the template from an input image. The input image dimensions must match the original. The input and original are overlaid onto the working image, from which the template is generated. Pixels that fall outside the mask are ignored in the f template.

Parameters:
image - the input image
alphaInput - the opacity with which the input image is overlaid (0-255)
alphaOriginal - the opacity with which the original image is overlaid (0-255)
Returns:
the template

getAlphas

public int[] getAlphas()
Gets the alphas used to build the most recent template.

Returns:
int[] {alphaInput, alphaOriginal}

setIndex

public void setIndex(int index)
Sets the index.

Parameters:
index - the index

getIndex

public int getIndex()
Gets the index. Note: index is not set internally, but only with calls to setIndex().

Returns:
the index

getWorkingPixels

public int[] getWorkingPixels(int[] pixels)
Gets the working image pixels used to generate the template.

Parameters:
pixels - int[] of pixels. If null, it will be created
Returns:
the filled pixels array

setWorkingPixels

public void setWorkingPixels(int[] pixels)
Sets the working image pixels used to generate the template.

Parameters:
pixels - int[] of pixels

getMatchLocation

public TPoint getMatchLocation(java.awt.image.BufferedImage target,
                               java.awt.Rectangle searchRect)
Gets the template location at which the best match occurs in a rectangle. May return null. Template matching process: 1. At each test position in the search area, find the RGB square deviation ("RGBSqD": sum of squares of rgb differences of all pixels) between the template and video image. Note that the RGBSqD is zero for a perfect match and larger for poorer matches. 2. Determine the average RGBSqD for all test positions. 3. Define the position for which the RGBSqD is minimum as the "working" best match. Define the peak height ("PH") of this match to be PH = (avgRGBSqD/matchRGBSqD)-1. Note that the PH may vary from zero to infinity. 4. If the PH exceeds the "Automark" setting, the match is deemed to be a good one (i.e., significantly better than average). 5. For sub-pixel accuracy, fit a Gaussian curve to the PHs of the working best match and its immediate vertical and horizontal neighbors. Note that the 3-point Gaussian fits should be exact. 6. The final best match (sub-pixel) is the position of the peak of the Gaussian fit. 7. Note that the width of the Gaussian fit is probably correlated with the uncertainty of the match position, but it is not used to explicitly estimate this uncertainty.

Parameters:
target - the image to search
searchRect - the rectangle to search within the target image
Returns:
the optimized template location at which the best match, if any, is found

getMatchLocation

public TPoint getMatchLocation(java.awt.image.BufferedImage target,
                               java.awt.Rectangle searchRect,
                               double x0,
                               double y0,
                               double theta,
                               int spread)
Gets the template location at which the best match occurs in a rectangle and along a line. May return null.

Parameters:
target - the image to search
searchRect - the rectangle to search within the target image
x0 - the x-component of a point on the line
y0 - the y-component of a point on the line
theta - the angle of the line
spread - the spread of the line (line width = 1+2*spread)
Returns:
the optimized template location of the best match, if any

getMatchImage

public java.awt.image.BufferedImage getMatchImage()
Gets the most recent match image.

Returns:
the best match image

getMatchWidthAndHeight

public double[] getMatchWidthAndHeight()
Returns the width and height of the peak for the most recent match. The peak height is the ratio meanSqPixelDiff/matchSqPixelDiff. The peak width is the mean of the vertical and horizontal Gaussian fit widths. This data can be used to determine whether a match is acceptable. A peak height greater than 5 is a reasonable standard for acceptability. Special cases: 1. If the match is perfect, then the height is infinite and the width NaN. 2. If the searchRect fell outside the target image, then no match was possible and both the width and height are NaN. 3. If there were no points to search along the 1D x-axis path, then the height is NaN and the width is negative. 4. If the Gaussian fit optimization was not successful (either horizontally or vertically) then the height is finite and the width is NaN.

Returns:
double[2] {mean Gaussian width, height}

getValue

public static int getValue(int a,
                           int argb)
Method to get the color value

Parameters:
a - 0-255 alpha
argb - current color value
Returns:
the integer value

getValue

public static int getValue(int a,
                           int r,
                           int g,
                           int b)
Method to get the color value

Parameters:
a - 0-255 alpha
r - 0-255 red
g - 0-255 green
b - 0-255 blue
Returns:
the integer value

getAlpha

public static int getAlpha(int value)
Method to get the alpha component from a color value

Parameters:
value - the color value
Returns:
0-255 alpha component

getRed

public static int getRed(int value)
Method to get the red component from a color value

Parameters:
value - the color value
Returns:
0-255 red component

getGreen

public static int getGreen(int value)
Method to get the green component from a color value

Parameters:
value - the color value
Returns:
0-255 green component

getBlue

public static int getBlue(int value)
Method to get the blue component from a color value

Parameters:
value - the color value
Returns:
0-255 blue component

getSearchPoints

public java.util.ArrayList<java.awt.geom.Point2D> getSearchPoints(java.awt.Rectangle searchRect,
                                                                  double x0,
                                                                  double y0,
                                                                  double theta)
Gets a list of Point2D objects that lie within pixels in a rectangle and along a line.

Parameters:
searchRect - the rectangle
x0 - the x-component of a point on the line
y0 - the y-component of a point on the line
theta - the angle of the line
Returns:
a list of Point2D