/**
*
*/
package fr.unistra.pelican.algorithms.morphology.connected;
import java.util.Stack;
import fr.unistra.pelican.Algorithm;
import fr.unistra.pelican.AlgorithmException;
import fr.unistra.pelican.BooleanImage;
import fr.unistra.pelican.Image;
import fr.unistra.pelican.algorithms.visualisation.MViewer;
import fr.unistra.pelican.gui.MultiViews.MultiView;
import fr.unistra.pelican.util.connectivityTrees.ComponentNode;
import fr.unistra.pelican.util.connectivityTrees.ComponentTree;
import fr.unistra.pelican.util.connectivityTrees.ComponentTreeUtil;
/**
* Extract all monomodal hyper-connected components of a tree marked by the masked.
*
* In other words delete all nodes of a connected components tree having an empty intersection with the given mask.
*
* Or in other words performs an opening by reconstruction ;)
*
* @author Benjamin Perret
*
*/
public class OpeningByReconstruction<T> extends Algorithm {
/**
* The component tree
*/
public ComponentTree<T> tree;
/**
* The mask
*/
public Image mask;
/**
*
*/
public OpeningByReconstruction() {
super();
super.inputs="tree,mask";
super.outputs="tree";
}
/* (non-Javadoc)
* @see fr.unistra.pelican.Algorithm#launch()
*/
@Override
public void launch() throws AlgorithmException {
int xdim=mask.xdim;
int ydim=mask.ydim;
int zdim=mask.zdim;
ComponentNode<T> root=tree.getRoot();
tree.resetFlag(0);
for(int z=0;z<zdim;z++)
for(int y=0;y<ydim;y++)
for(int x=0;x<xdim;x++)
if(mask.getPixelXYZBoolean(x, y, z))
{
ComponentNode<T> n = tree.findNodeAt(x, y, z);
while(n!=root && n!=null)
{
n.flag=1;
n=n.parent;
}
//tree.compressPathFinding(); // path becoming too long... stack becoming too short!
}
Stack<ComponentNode<T>> s= new Stack<ComponentNode<T>>();
root.flag=1;
s.push(root);
while(!s.isEmpty())
{
ComponentNode<T> n =s.pop();
for(ComponentNode<T> c:n.getChildren())
s.push(c);
if(n.flag==0)
tree.deleteNode(n);
}
}
public static <T> ComponentTree<T> exec (ComponentTree<T> tree, Image mask)
{
return (ComponentTree<T>)(new OpeningByReconstruction<T>()).process(tree,mask);
}
public static void main(String [] args)
{
ComponentTree<Double> tree=ComponentTreeUtil.getTestCase();
BooleanImage mask=new BooleanImage(tree.getXdim(),tree.getYdim(),1,1,1);
mask.setPixelXYBoolean(1, 0, true);
mask.setPixelXYBoolean(2, 0, true);
//mask.fill(true);
MultiView mv=MViewer.exec();
mv.add(tree.image,"Original");
mv.add(mask,"mask");
tree.debugDropNodeMap();
System.out.println(tree.getRoot());
tree=OpeningByReconstruction.exec(tree, mask);
tree.debugDropNodeMap();
mv.add(ReconstructImageFromTree.exec(tree),"reconstruct");
}
}