package fr.unistra.pelican.algorithms.segmentation.labels;
import java.util.Arrays;
import fr.unistra.pelican.Algorithm;
import fr.unistra.pelican.Image;
import fr.unistra.pelican.IntegerImage;
/**
* Merge the labels of connected regions belonging to the same class in N Dimensions
*
* @author Jonathan Weber
*/
public class MergeLabelsFromClassesND extends Algorithm {
/**
*
* Label Image
*/
public Image labelImage;
/**
* Class Image
*/
public Image classImage;
/**
* Flag for 4-connexity
*/
public boolean connexity4 = false;
/**
* result
*/
public Image outputImage;
/**
* Constructor
*
*/
public MergeLabelsFromClassesND() {
super.inputs = "labelImage,classImage";
super.options = "connexity4";
super.outputs = "outputImage";
}
public void launch() {
outputImage = labelImage.copyImage(false);
int xdim = labelImage.getXDim();
int ydim = labelImage.getYDim();
int zdim = labelImage.getZDim();
int tdim = labelImage.getTDim();
int bdim = labelImage.getBDim();
// Récupération de la classe de chaque label
if (!Image.haveSameDimensions(labelImage, classImage)) {
System.err
.println("MergeLabelsFromClassesND: labelImage and classImage do not have same dimensions");
return;
}
// Décompte du nombre de labels
int maxLabel = 0;
for (int p = 0; p < labelImage.size(); p++)
if (labelImage.getPixelInt(p) > maxLabel)
maxLabel = labelImage.getPixelInt(p);
// Association des labels au classes
int tabLabel[] = new int[maxLabel + 1];
Arrays.fill(tabLabel, -1);
for (int p = 0; p < labelImage.size(); p++) {
int val = labelImage.getPixelInt(p);
if (tabLabel[val] == -1 && classImage.getPixelInt(p) != 0)
tabLabel[val] = classImage.getPixelInt(p);
}
// Création de la table d'équivalence
int newLabel[] = new int[maxLabel + 1];
int newLabel2[] = new int[maxLabel + 1];
for (int tt = 0; tt < newLabel.length; tt++)
newLabel[tt] = tt;
// Parcours de l'image de label et recherche des zones connexes
for(int b=0;b<bdim;b++)
for(int t=0;t<tdim;t++)
for(int z=0;z<zdim;z++)
for (int y = 0; y < ydim; y++)
for (int x = 0; x < xdim; x++) {
int val = labelImage.getPixelInt(x, y, z, t, b);
for (int bb = -1; bb <= 1; bb++)
for (int tt = -1; tt <= 1; tt++)
for (int zz = -1; zz <= 1; zz++)
for (int yy = -1; yy <= 1; yy++)
for (int xx = -1; xx <= 1; xx++)
if ((xx!=0||xdim==1)&&(yy!=0||ydim==1)&&(zz!=0||zdim==1)&&(tt!=0||tdim==1)&&(bb!=0||bdim==1)
&&x+xx>=0&&y+yy>=0&&z+zz>=0&&t+tt>=0&&b+bb>=0
&&x+xx<xdim&&y+yy<ydim&&z+zz<zdim&&t+tt<tdim&&b+bb<bdim)
{
int val2 = labelImage
.getPixelInt(x + xx, y + yy, z+zz, t+tt, b+bb);
// Si les 2 zones connexes sont de la même classe, on met
// à
// jour la table d'équivalence
if (val2 != val && newLabel[val2] != newLabel[val]
&& tabLabel[val2] == tabLabel[val]) {
newLabel[val]=Math.min(newLabel[val], newLabel[val2]);
newLabel[val2]=Math.min(newLabel[val], newLabel[val2]);
//newLabel[Math.max(val, val2)] = Math.min(val, val2);
System.out.println(Math.max(val, val2)+" => "+Math.min(val, val2));
}
}
}
// Simplification de la table de labels
int nbLabels = 0;
for (int tt = 0; tt < newLabel.length; tt++) {
if (newLabel[tt] == tt)
newLabel2[tt] = nbLabels++;
System.out.println(tt+" "+tabLabel[tt]+" "+newLabel[tt]+" "+newLabel2[newLabel[tt]]);
}
// Nouveau parcours pour mise à jour des labels
for(int b=0;b<bdim;b++)
for(int t=0;t<tdim;t++)
for(int z=0;z<zdim;z++)
for (int y = 0; y < ydim; y++)
for (int x = 0; x < xdim; x++)
outputImage.setPixelInt(x, y, z, t, b,
newLabel2[newLabel[labelImage.getPixelInt(x, y, z, t, b)]]);
}
public static IntegerImage exec(Image labelImage, Image classImage) {
return (IntegerImage) new MergeLabelsFromClassesND().process(labelImage,
classImage);
}
public static Image exec(Image labelImage, Image classImage,
boolean connexity4) {
return (IntegerImage) new MergeLabelsFromClassesND().process(labelImage,
classImage, connexity4);
}
}