package fr.unistra.pelican.algorithms.segmentation.regionMerging;
import java.util.Vector;
import fr.unistra.pelican.Algorithm;
import fr.unistra.pelican.AlgorithmException;
import fr.unistra.pelican.Image;
/**
* A classical region merger. Merge each connected regions if their mean value (Euclidian distance)
* is below threshold.
*
* @author Sébastien Derivaux, Jonathan Weber
*/
public class MergeByErrorReduction extends Algorithm {
// Inputs parameters
public Image labelImage;
public Image baseImage;
public double threshold;
// Outputs parameters
public Image outputImage;
/**
* Constructor
*
*/
public MergeByErrorReduction() {
super();
super.inputs = "labelImage,baseImage,threshold";
super.outputs = "outputImage";
;
}
/*
* (non-Javadoc)
*
* @see fr.unistra.pelican.Algorithm#launch()
*/
public void launch() throws AlgorithmException {
outputImage = baseImage.copyImage(false);
Vector<double[]> labels = new Vector<double[]>();
// Grab all pixels values
int xDim = outputImage.getXDim();
int yDim = outputImage.getYDim();
int zDim = outputImage.getZDim();
int tDim = outputImage.getTDim();
int bDim = outputImage.getBDim();
for (int x = 0; x < xDim; x++)
for (int y = 0; y < yDim; y++)
for (int z=0; z<zDim;z++)
for(int t=0;t<tDim;t++)
{
int label = labelImage.getPixelXYZTBInt(x, y,z,t, 0);
if (labels.size() <= label)
labels.setSize(label + 1);
// value[0] = number of pixels
// value[b] = sum of pixels with this label for band b
double value[] = labels.get(label);
if (value == null) {
value = new double[bDim + 1];
}
value[0] = value[0] + 1.0;
for (int b = 0; b < bDim; ++b)
value[b + 1] += baseImage.getPixelXYZTBDouble(x, y,z,t, b);
labels.set(label, value);
}
// Calculate the mean.
for (int i = 0; i < labels.size(); i++)
for (int b = 0; b < bDim; ++b) {
double value[] = labels.get(i);
if (value == null)
continue;
value[b + 1] = value[b + 1] / value[0];
}
// Set each pixel value
for (int x = 0; x < xDim; x++)
for (int y = 0; y < yDim; y++)
for (int z=0; z<zDim;z++)
for(int t=0;t<tDim;t++)
{
int label = labelImage.getPixelXYZTBInt(x, y, z, t, 0);
double value[] = labels.get(label);
if (value == null)
throw new AlgorithmException(
"Label with no pixel but in use????");
for (int b = 0; b < bDim; ++b)
outputImage.setPixelXYZTBDouble(x, y, z, t, b, value[b + 1]);
}
}
public static Image exec(Image labelImage, Image baseImage, double threshold) {
return (Image)new MergeByErrorReduction().process(labelImage, baseImage, threshold);
}
}