package fr.unistra.pelican.algorithms.morphology.binary;
import fr.unistra.pelican.Algorithm;
import fr.unistra.pelican.AlgorithmException;
import fr.unistra.pelican.BooleanImage;
import fr.unistra.pelican.util.morphology.FlatStructuringElement2D;
/**
* Compute an angular granulometry with line SE
*
* @author Lefevre
*
*/
public class BinaryAngularGranulometry extends Algorithm {
/**
* Image to be processed
*/
public BooleanImage inputImage;
/**
* Number of SE lengths
*/
public Integer length;
/**
* Number of SE angles
*/
public Integer angles;
/**
* Flag to compute differential granulometry instead of standard one
*/
public boolean diff = false;
/**
* Granulometry array
*/
public Double[][] outputTab;
/**
* Constructor
*
*/
public BinaryAngularGranulometry() {
super.inputs = "inputImage,length,angles";
super.options = "diff";
super.outputs = "outputTab";
}
/*
* (non-Javadoc)
*
* @see fr.unistra.pelican.Algorithm#launch()
*/
public void launch() throws AlgorithmException {
// Initialisation
outputTab = new Double[length][angles];
// Compute the total number of pixels to be used in the ratio measure
double total = inputImage.getSum();
// Computation of the granulometry
for (int i = 0; i < length; i++)
for (int a = 0; a < angles; a++) {
BooleanImage se=FlatStructuringElement2D.createLineFlatStructuringElement(2*i+1, a*180/angles);
//BooleanImage open = BinaryOpening.exec(inputImage,se);
BooleanImage open = BinaryErosion.exec(inputImage,se);
open= BinaryDilation.exec(open,se);
// Compute the number of pixels after the opening
double nb = open.getSum();
outputTab[i][a] = nb / total;
}
if (diff) {
Double outputTab2[][] = new Double[length][angles];
for (int i = 0; i < length; i++)
for (int j = 0; j < angles; j++) {
if (i == 0 && j == 0)
outputTab2[i][j] = 0.0;
else if (i == 0)
outputTab2[i][j] = outputTab[i][j - 1]
- outputTab[i][j];
else if (j == 0)
outputTab2[i][j] = outputTab[i - 1][j]
- outputTab[i][j];
else
outputTab2[i][j] = 2 * outputTab[i - 1][j - 1]
- outputTab[i][j - 1] - outputTab[i - 1][j];
outputTab2[i][j] /= 2;
}
outputTab = outputTab2;
}
}
/**
* This method computes a 2D granulometry using rectangular SE and efficient
* implementation.
*
* @param inputImage
* Image to be processed
* @param xMax
* Limit max of SE's length
* @param yMax
* Limit max of SE's width
* @param step
* Step for SE's size variation
* @param angle
* SE's angle rotation
* @return 2D granulometry
*/
public static Double[][] exec(BooleanImage inputImage, Integer length,
Integer angles) {
return (Double[][]) new BinaryAngularGranulometry().process(inputImage,
length, angles);
}
public static Double[][] exec(BooleanImage inputImage, Integer length,
Integer angles, boolean diff) {
return (Double[][]) new BinaryAngularGranulometry().process(inputImage,
length, angles, diff);
}
}