Commit 1c0afdcc authored by lafabregue's avatar lafabregue

first released version v6.0

parents
temporary/*
*.class
# eclipse specific git ignore
*.pydevproject
.project
.metadata
bin/**
tmp/**
tmp/**/*
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
*.hprof
12
\ No newline at end of file
12
\ No newline at end of file
package jsl.segmentation;
import image.Image;
import image.IntegerImage;
import image.algorithms.Algorithm;
import image.algorithms.AlgorithmException;
import java.awt.Point;
import java.util.Stack;
import jsl.io.ImageData;
import jsl.utils.Progressable;
/**
* Interface pour les algorithmes de segmentation. Un segmenteur doit surcharger au choix : -
* buildSegmentation(RawImage image) - buildSegmentation(fr.unistra.pelican.Image image) Par contre
* en fait pour l'instant il faut de toute facon surcharger
* buildSegmentation(fr.unistra.pelican.Image image) cf le
* @author derivaux
*/
public abstract class Segmenteur implements Cloneable, Progressable {
/** Parametres de la methode de segmentation */
public Parametres paramSegmenteur;
/** IO Image */
public ImageData image;
/** Resultat segmenteur */
public Resultat resultatSegmenteur;
/**
* Parametre de progression pour l'affichage de la barre de progression
*/
public int progress = 0;
/**
* Valeur maximale de la progression
*/
public int progressM = 100;
/**
* Constructeur par defaut
*/
public Segmenteur() {}
/**
* Constructeur avec passage de paramétres
* @param resultatSegmenteur
*/
public Segmenteur(Parametres params, ImageData image, Resultat resultat) {
super();
this.paramSegmenteur = params;
this.image = image;
this.resultatSegmenteur = resultat;
}
abstract protected void build(Image image);
abstract public Segmenteur copy();
/**
* @param image Pelican Initial avant le processus de segmenteur
*/
final public void run() {
this.progressM = 2;
this.build(this.image.imageBrutePiaf);
this.incProgress();
this.endProgress();
}
public void setResultatImage(Image imageLabels) {
this.resultatSegmenteur.setLabelsPiaf(imageLabels);
}
public int getNiveaux() {
return 1;
}
/**
* get nom segmenteur
*/
abstract public String getNomSegmenteur();
/*
* ================================================================================= GETERS and
* SETers
*/
@Override
public Object clone() throws CloneNotSupportedException {
return this.copy();
}
@Override
public void endProgress() {
this.progress = this.progressM;
}
@Override
public int getProgress() {
return (int) (((double) this.progress / (double) this.progressM) * 100.0);
}
@Override
public void incProgress() {
this.progress++;
}
@Override
public void resetProgress() {
this.progress = 0;
}
@Override
public void setProgress(int value) {
this.progressM = value;
}
public Resultat getResultatSegmenteur() {
return resultatSegmenteur;
}
public void setResultatSegmenteur(Resultat resultatSegmenteur) {
this.resultatSegmenteur = resultatSegmenteur;
}
public Parametres getParamSegmenteur() {
return paramSegmenteur;
}
public void setParamSegmenteur(Parametres paramSegmenteur) {
this.paramSegmenteur = paramSegmenteur;
}
/**
* Create a segment for each "composantes connexe". Use 8-connexity. Use equality for pixels on
* integer level.
*/
public class SegmentByConnexity extends Algorithm {
public Image exec(Image image) {
return (Image) new SegmentByConnexity().process(image);
}
// Inputs parameters
public Image inputImage;
// Outputs parameters
public IntegerImage outputImage;
/**
* Constructor
*/
public SegmentByConnexity() {
super();
super.inputs = "inputImage";
super.outputs = "outputImage";
super.help = "Segment image by 8-connexity.\n" + "Image inputImage\n" + "\n" + "Image outputImage\n" + "\n" + "";
}
private boolean areEquals(int x1, int y1, int x2, int y2) {
for (int b = 0; b < inputImage.getBDim(); b++)
if (inputImage.getPixelXYBInt(x1, y1, b) != inputImage.getPixelXYBInt(x2, y2, b))
return false;
return true;
}
/*
* (non-Javadoc)
* @see fr.unistra.pelican.Algorithm#launch()
*/
@Override
public void launch() throws AlgorithmException {
outputImage = new IntegerImage(inputImage.getXDim(), inputImage.getYDim(), 1, 1, 1);
outputImage.fill(-1);
int xDim = outputImage.getXDim();
int yDim = outputImage.getYDim();
int bDim = inputImage.getBDim();
int label = 0;
for (int x = 0; x < xDim; x++)
for (int y = 0; y < yDim; y++)
if (outputImage.getPixelXYInt(x, y) == -1)
newSegment(x, y, label++);
outputImage.setProperty("nbRegions", label);
}
private void newSegment(int x, int y, int label) {
outputImage.setPixelXYInt(x, y, label);
Stack<Point> fifo = new Stack<Point>();
fifo.push(new Point(x, y));
while (!fifo.empty()) {
Point p = fifo.pop();
outputImage.setPixelXYInt(p.x, p.y, label);
// For every pixel in the 8-neighbourhood of the pixel
for (int l = p.y - 1; l <= p.y + 1; l++) {
for (int k = p.x - 1; k <= p.x + 1; k++) {
if (k < 0 || k >= inputImage.getXDim() || l < 0 || l >= inputImage.getYDim())
continue;
if (!(k == p.x && l == p.y)) {
if (outputImage.getPixelXYInt(k, l) == -1 && areEquals(p.x, p.y, k, l))
fifo.push(new Point(k, l));
}
}
}
}
}
}
}
package jsl.segmentation.methodes.hierarchicalBinaryPartitionTree.utils;
import image.Image;
import image.IntegerImage;
import java.awt.Point;
import java.util.*;
/**
* Create a segment for each "composantes connexe". Use 8-connexity. Use equality for pixels on
* integer level.
*/
public class SegmentByConnexityPelicanInteger {
// Inputs parameters
public Image inputImagePelican;
public HashMap<Integer, ArrayList<Integer>> inputRegion;
public int xDim;
public int yDim;
public int bDim;
// Outputs parameters
public IntegerImage outputImage;
HashMap<Integer, Integer> output = new HashMap<Integer, Integer>();
/**
* Constructor
*/
public SegmentByConnexityPelicanInteger(Image src) {
this.inputImagePelican = src;
xDim = this.inputImagePelican.xdim;
yDim = this.inputImagePelican.ydim;
bDim = this.inputImagePelican.bdim;
}
public SegmentByConnexityPelicanInteger(HashMap<Integer, ArrayList<Integer>> regionToSegment, int XDim, int YDim, int BDim) {
this.inputRegion = regionToSegment;
xDim = XDim;
yDim = YDim;
bDim = BDim;
}
public Image runForFullImage() {
outputImage = new IntegerImage(inputImagePelican.xdim, inputImagePelican.ydim, 1, 1, 1);
outputImage.fill(-1);
int label = 0;
for (int x = 0; x < xDim; x++)
for (int y = 0; y < yDim; y++)
if (outputImage.getPixelXYInt(x, y) == -1)
newSegmentForFullImage(x, y, label++);
outputImage.setProperty("nbRegions", label);
return outputImage;
}
public HashMap<Integer, Integer> runForRegions() {
for (int p : inputRegion.keySet()) {
output.put(p, -1);
}
int label = 0;
for (int p : inputRegion.keySet()) {
int x = p % xDim;
int y = p / xDim;
if (output.get(p) == -1) {
newSegmentForRegions(x, y, label++);
}
}
return output;
}
private void newSegmentForFullImage(int x, int y, int label) {
outputImage.setPixelXYInt(x, y, label);
Stack<Point> fifo = new Stack<Point>();
fifo.push(new Point(x, y));
while (!fifo.empty()) {
Point p = fifo.pop();
outputImage.setPixelXYInt(p.x, p.y, label);
// For every pixel in the 8-neighbourhood of the pixel
for (int l = p.y - 1; l <= p.y + 1; l++) {
for (int k = p.x - 1; k <= p.x + 1; k++) {
if (k < 0 || k >= xDim || l < 0 || l >= yDim)
continue;
if (!(k == p.x && l == p.y)) {
if (outputImage.getPixelXYInt(k, l) == -1 && areEqualsForFullImage(p.x, p.y, k, l)) {
fifo.push(new Point(k, l));
}
}
}
}
}
}
private void newSegmentForRegions(int x, int y, int label) {
output.put((y * xDim) + x, label);
Stack<Point> fifo = new Stack<Point>();
fifo.push(new Point(x, y));
while (!fifo.empty()) {
Point p = fifo.pop();
output.put(p.y * xDim + p.x, label);
// For every pixel in the 8-neighbourhood of the pixel
for (int l = p.y - 1; l <= p.y + 1; l++) {
for (int k = p.x - 1; k <= p.x + 1; k++) {
if (k < 0 || k >= xDim || l < 0 || l >= yDim)
continue;
if (!(k == p.x && l == p.y) && inputRegion.containsKey(l * (xDim) + k)) {
if (output.get(l * (xDim) + k) == -1 && areEqualsRegion(p.x, p.y, k, l)) {
fifo.push(new Point(k, l));
}
}
}
}
}
}
private boolean areEqualsForFullImage(int x1, int y1, int x2, int y2) {
for (int b = 0; b < bDim; b++)
if (inputImagePelican.getPixelXYBInt(x1, y1, b) != inputImagePelican.getPixelXYBInt(x2, y2, b))
return false;
return true;
}
private boolean areEqualsRegion(int x1, int y1, int x2, int y2) {
int p1 = y1 * xDim + x1;
int p2 = y2 * xDim + x2;
for (int b = 0; b < bDim; b++) {
if (inputRegion.get(p1).get(b).intValue() != inputRegion.get(p2).get(b).intValue()) {
return false;
}
}
return true;
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
package image.algorithms.morphology.gray;
import image.BooleanImage;
import image.Image;
import image.algorithms.Algorithm;
import image.utils.Point4D;
/**
* This class performs a gray erosion with a 2-D flat structuring element
*
* @author
*/
public class GrayErosion extends Algorithm {
/**
* The input image
*/
public Image inputImage;
/**
* The flat structuring element used in the morphological operation
*/
public BooleanImage se;
/**
* The output image
*/
public Image outputImage;
/**
* Default constructor
*/
public GrayErosion() {
super.inputs = "inputImage,se";
super.outputs = "outputImage";
}
/**
* Performs a gray erosion with a 2-D flat structuring element
*
* @param image
* The input image
* @param se
* The flat structuring element used in the morphological operation
* @return The output image
*/
public static Image exec(Image inputImage, BooleanImage se) {
return (Image) new GrayErosion().process(inputImage, se);
}
/**
* Performs a gray erosion with a 2-D flat structuring element and a mask
*
* @param image
* The input image
* @param se
* The flat structuring element used in the morphological operation
* @param mask
* Mask used to compute a part of the image
*
* @return The output image
*/
public static Image exec(Image inputImage, BooleanImage se, Image mask) {
return (Image) new GrayErosion().process(inputImage, se, mask);
}
/*
* (non-Javadoc)
*
* @see fr.unistra.pelican.Algorithm#launch()
*/
public void launch() {
outputImage = inputImage.copyImage(false);
int xDim = inputImage.getXDim();
int yDim = inputImage.getYDim();
int tDim = inputImage.getTDim();
int bDim = inputImage.getBDim();
int zDim = inputImage.getZDim();
Point4D[] points = se.foreground();
boolean isHere;
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++ ) {
isHere = this.inputImage.isPresent( x,y,z,t,b );
if ( !isHere ) outputImage.setPixelDouble( x,y,z,t,b, 0 );
else outputImage.setPixelDouble( x,y,z,t,b, getMinGray( x,y,z,t,b, points) );
}
}
/*
* Return the min value under a flat structuring element.
*/
private double getMinGray(int x, int y, int z, int t, int b, Point4D[] points) {
double min = Double.MAX_VALUE;
boolean flag = false;
for (int i = 0; i < points.length; i++) {
int valX = x - se.getCenter().x + points[i].x;
int valY = y - se.getCenter().y + points[i].y;
int valZ = z - se.getCenter().z + points[i].z;
int valT = t - se.getCenter().t + points[i].t;
if ( valX >= 0 && valX < inputImage.getXDim()
&& valY >= 0 && valY < inputImage.getYDim()
&& valZ >= 0 && valZ < inputImage.getZDim()
&& valT >= 0 && valT < inputImage.getTDim()
&& inputImage.isPresent( valX,valY,valZ,valT,b ) ) {
double value = inputImage.getPixelDouble(valX, valY, valZ, valT, b);
if (min > value)
min = value;
flag = true;
}
}
// FIXME: Strange, if nothing is under the se, what is the right way?
return (flag == true) ? min : inputImage.getPixelDouble(x, y, z, t, b);
}
}
package jsl.segmentation.methodes.regionmerging.utilsregionmerging.adjacenceutils;