/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package jjil.algorithm;
import jjil.core.Error;
import jjil.core.Gray8Image;
import jjil.core.Image;
import jjil.core.PipelineStage;
import jjil.core.RgbImage;
import jjil.core.RgbVal;
/**
* Compute the Gray8Image that is the minimum absolute difference in red, green,
* or blue between the RgbImage specified in the constructor and the RgbImage
* supplied to the pipeline stage. This is intended to be used as part of a
* pipeline for separating out a fixed background from the new input. Since
* the background can vary due to lighting conditions we find the maximum
* difference in any color channel and output that, making it easier to find
* objects that may match the background in one or two channels.
* @author webb
*/
public class RgbMinDiff extends PipelineStage {
private RgbImage rgbBack;
/**
* Set background image.
* @param rgbBack background RgbImage.
*/
public RgbMinDiff(RgbImage rgbBack) {
this.rgbBack = rgbBack;
}
/**
* Process a foreground RgbImage and produce a Gray8Image in which each
* pixel is the maximum of the differences between the input image and
* the background image in the three color channels.
* @param imInput input RgbImage
* @throws jjil.core.Error if imInput is not an RgbImage or is not the same
* size as the background image set in the constructor.
*/
public void push(Image imInput) throws Error {
{
if (!(imInput instanceof RgbImage))
throw new Error(
Error.PACKAGE.ALGORITHM,
ErrorCodes.IMAGE_NOT_RGBIMAGE,
imInput.toString(),
null,
null);
}
if (imInput.getWidth() != this.rgbBack.getWidth() ||
imInput.getHeight() != this.rgbBack.getHeight()) {
throw new Error(
Error.PACKAGE.ALGORITHM,
ErrorCodes.IMAGE_SIZES_DIFFER,
imInput.toString(),
this.rgbBack.toString(),
null);
}
int wInput[] = ((RgbImage)imInput).getData();
int wBack[] = this.rgbBack.getData();
Gray8Image grayOut = new Gray8Image(
this.rgbBack.getWidth(),
this.rgbBack.getHeight());
byte bGray[] = grayOut.getData();
for (int i=0; i<imInput.getWidth() * imInput.getHeight(); i++) {
int rIn = RgbVal.getR(wInput[i]);
int gIn = RgbVal.getG(wInput[i]);
int bIn = RgbVal.getB(wInput[i]);
int rBack = RgbVal.getR(wBack[i]);
int gBack = RgbVal.getG(wBack[i]);
int bBack = RgbVal.getB(wBack[i]);
int gRes = Math.min(Math.abs(rIn-rBack),
Math.min(Math.abs(gIn-gBack),
Math.abs(bIn-bBack)));
bGray[i] = (byte) Math.min(gRes, Byte.MAX_VALUE);
}
super.setOutput(grayOut);
}
/**
* Implement toString, providing the background image information.
* @return a string consisting of this class name followed by the
* background image description.
*/
public String toString() {
return super.toString() + "(" + this.rgbBack.toString() + ")";
}
}