Commit 6f180691 authored by lafabregue's avatar lafabregue
Browse files

Integrate sampling and new file reading tools based on bio-format library

parent a3020548
......@@ -259,7 +259,7 @@ public abstract class Classification extends Observable implements
texte += "<h3>Information</h3>";
texte += "<hr>";
texte += "<p>Nb attributes : "
+ this.getData().getDataObject(0).getNbAttributes() + "</p>";
+ this.getData().getOneDataObject().getNbAttributes() + "</p>";
texte += "<p>Nb objects" + " : " + this.getData().getNbObjects()
+ "</p>";
......
......@@ -9,250 +9,75 @@ import jcl.weights.Weights;
/**
* <p>
* Classe implantant la notion de 'classe' (cluster).
* Class that implements the class notion (cluster)
* </p>
*
* @author Alexandre BLANSCHE
* @author Alexandre BLANSCHE / Baptiste LAFABREGUE
*/
public class Cluster implements Serializable {
abstract public class Cluster implements Serializable {
/** */
private static final long serialVersionUID = 1L;
/** Le centre de gravite de ce cluster */
private DataObject clusterCenter = null;
/** The cluster's gravity center */
protected DataObject clusterCenter = null;
/** La couleur associee a ce cluster */
private Color color = new Color(0);
/** The cluster's associated color */
protected Color color = new Color(0);
/** La couleur du noeud pere de ce cluster */
private Color couleur_pere = new Color(0);
/** Les donnees appartenant e ce cluster */
private Data data = null;
/** The cluster's father node color*/
protected Color couleur_pere = new Color(0);
/**
* Le cluster est-il gele ou non ? Si il est gele, on ne peut pas lui
* appliquer d'operateur
* Indicate if the cluster is freezed or not. If it is, we
* cannot apply an operator on it.
*/
private boolean locked = false;
protected boolean locked = false;
/** Le degre d'appartenance de chaque objet a ce cluster */
private double membershipDegree[] = null;
/** Probabilite de la classe (pour EM) */
private double membershipProbabilityEM = 0;
/** The cluster's name */
protected String name = "";
/** Le nom du cluster */
private String name = "";
/** False if the cluster should be masked in the result image */
protected boolean visible = true;
/** The attributes weights */
protected Weights weights = null;
/**
* Faux si on veut masquer le cluster dans l'image résultat
* Empty constructor
*/
private boolean visible = true;
/** Les ponderations des attributs */
private Weights weights = null;
public Cluster() {
}
/**
* <p>
* Constructeur.
* </p>
* Copy constructor
*
* @param cluster
* une classe
* the cluster to copy
*/
public Cluster(final Cluster cluster) {
this.data = new Data(cluster.data);
this.membershipDegree = new double[cluster.membershipDegree.length];
for (int i = 0; i < this.membershipDegree.length; i++) {
this.membershipDegree[i] = cluster.getMembership(i);
}
public Cluster(Cluster cluster) {
this.locked = cluster.locked;
this.name = new String(cluster.name);
this.color = new Color(cluster.getColor().getRGB());
if (cluster.clusterCenter != null) {
this.clusterCenter = new DataObject(cluster.clusterCenter);
} else {
this.clusterCenter = this.computeCenter();
}
}
this.weights = new Weights(cluster.weights);
this.membershipProbabilityEM = cluster.membershipProbabilityEM;
}
/**
* <p>
* Constructeur. (principal)
* </p>
*
* @param data
* l'ensemble de donnees d'o� est extraite la classe
* @param clusterMap
* la carte de classification
* @param k
* l'index de la classe
* @param weights
* le vecteur de poid associe a la classe
* @param membershipDegree
* le degre d'appartenance de tous les objets a la classe
* @param proba
* probabilite qu'un objet appartienne a cette classe
*/
public Cluster(final Data data, final int clusterMap[], final int k,
final Weights weights, final double membershipDegree[],
final double proba) {
int c = 0;
this.weights = weights;
this.membershipDegree = new double[clusterMap.length];
if (membershipDegree != null) {
for (int i = 0; i < clusterMap.length; i++) {
if (clusterMap[i] == k) {
c++;
}
this.membershipDegree[i] = membershipDegree[i];
}
} else {
for (int i = 0; i < clusterMap.length; i++) {
if (clusterMap[i] == k) {
c++;
this.membershipDegree[i] = 1.;
} else {
this.membershipDegree[i] = 0.;
}
}
}
// TODO this.data = new Data(c, data.getStructure());
this.data = new Data(c);
this.data.setComments(data.getComments());
this.data.setDataName(data.getDataName());
this.data.setAttributesNames(data.getAttributesNames());
c = 0;
for (int i = 0; i < clusterMap.length; i++) {
if (clusterMap[i] == k) {
this.data.setDataObject(c, data.getDataObject(i));
c++;
}
}
if (this.data.getNbObjects() != 0) {
this.clusterCenter = this.computeCenter();
} else {
this.setVisible(false);
// System.out.println("attention, creation d'un cluster vide.");
}
this.membershipProbabilityEM = proba;
this.locked = false;
this.name = "Cluster " + (k + 1);
}
/**
* <p>
* Constructeur.
* </p>
*
* @param center
* centre de la classe
* @param data
* l'ensemble de donnees d'o� est extraite la classe
* @param clusterMap
* la carte de classification
* @param k
* l'index de la classe
* @param weights
* le vecteur de poid associe a la classe
* @param membershipDegree
* le degre d'appartenance de tous les objets a la classe
* @param proba
* probabilite qu'un objet appartienne a cette classe
*/
public Cluster(final DataObject center, final Data data,
final int clusterMap[], final int k, final Weights weights,
final double membershipDegree[], final double proba) {
int c = 0;
this.weights = weights;
this.membershipDegree = new double[clusterMap.length];
if (membershipDegree != null) {
for (int i = 0; i < clusterMap.length; i++) {
if (clusterMap[i] == k) {
c++;
}
this.membershipDegree[i] = membershipDegree[i];
}
} else {
for (int i = 0; i < clusterMap.length; i++) {
if (clusterMap[i] == k) {
c++;
this.membershipDegree[i] = 1.;
} else {
this.membershipDegree[i] = 0.;
}
}
}
// TODO this.data = new Data(c, data.getStructure());
this.data = new Data(c);
this.data.setComments(data.getComments());
this.data.setDataName(data.getDataName());
this.data.setAttributesNames(data.getAttributesNames());
c = 0;
for (int i = 0; i < clusterMap.length; i++) {
if (clusterMap[i] == k) {
this.data.setDataObject(c, data.getDataObject(i));
c++;
}
}
if (this.data.getNbObjects() != 0) {
this.clusterCenter = center;
} else {
this.setVisible(false);
// System.out.println("attention, creation d'un cluster vide.");
}
this.membershipProbabilityEM = proba;
this.locked = false;
this.name = "Cluster " + (k + 1);
}
/** Renvoi le centroide du cluster et le calcul si il est vide */
abstract public DataObject getCenter();
/**
* <p>
* Constructeur a partir d'un nom. ( utilisé pour construire une hiérarchie
* avec la méthodre arbreCobWeb() )
* </p>
*
* @param name
* le nom du cluster
*/
public Cluster(final String name) {
this.name = name;
}
@Override
public Object clone() {
return new Cluster(this);
}
// computes this.clusterCenter from this.data
private DataObject computeCenter() {
// TODO: intégrer l'utilisation des valeurs de membershipDegree
return this.data.mean();
}
/**
* <p>
* Distance euclidienne entre le centre de la classe et un objet.
* Euclidean distance from the center of the class and an object.
* </p>
*
* @param o
* un objet
* @return la distance entre le centre un objet o
* the object
* @return the distance between the center and o
*/
public double distance(final DataObject o) {
return this.clusterCenter.distance2(o, this.weights);
......@@ -260,14 +85,14 @@ public class Cluster implements Serializable {
/**
* <p>
* Distance entre le centre de la classe et un objet.
* Weighted distance from the center of the class and an object.
* </p>
*
* @param o
* un objet
* the object
* @param weights
* un vecteur de poids
* @return la distance entre le centre un objet o
* a weight vector
* @return the distance between the center and oo
*/
public double distance(final DataObject o, final Weights weights) {
return this.clusterCenter.distance(o, weights);
......@@ -282,10 +107,7 @@ public class Cluster implements Serializable {
* index de l'objet de la classe
* @return la distance entre le centre le o-ieme objet de la classe
*/
public double distance(final int o) {
return this.clusterCenter.distance(this.data.getDataObject(o),
this.weights);
}
abstract public double distance(final int o);
/**
* <p>
......@@ -294,12 +116,7 @@ public class Cluster implements Serializable {
*
* @return le cardinal de la classe
*/
public int getCard() {
if (this.data == null) {
return 0;
}
return this.data.getNbObjects();
}
abstract public int getCard();
/**
* <p>
......@@ -334,38 +151,30 @@ public class Cluster implements Serializable {
/**
* <p>
* Les objets de la classe.
* The objects from the class
* Warning this method might be CPU and memory consuming
* It might be better to work directly with the ClusteringResult for the DataObjects
* </p>
*
* @return les objets de la classe
* @parma fromSample
* tells if we want the Data based on object from the sample or the whole data
*
* @return the Data composed of object from this cluster
*/
public Data getData() {
return this.data;
}
abstract public Data getData(boolean fromSample);
/**
* <p>
* Objet de la classe.
* Attention cette methode peut etre EXTREMEMENT consommatrice de CPU et de memoire
* Il est preferable de travailler directement avec le ClusteringResult pour les DataObjects
* </p>
*
* @param objIndex
* l'index de l'objet dans la classe
* @return le l'objet à l'indice objIndex
*/
public DataObject getObject(final int objIndex) {
// gets the array of every objects in the cluster
DataObject[] objectsArray;
objectsArray = this.data.getDataObjects();
// check if objIndex is ok
if (objIndex >= objectsArray.length) {
System.out.println("error: class Cluster, method getObject");
return null;
}
// returns requested object
return objectsArray[objIndex];
}
abstract public DataObject getObject(final int objIndex);
/**
* <p>
......@@ -376,14 +185,7 @@ public class Cluster implements Serializable {
* l'index de l'objet
* @return le degre d'appartenance du o-ieme objet e la classe
*/
public double getMembership(final int o) {
double degree = 0;
if ((o >= 0) && (o < this.membershipDegree.length)) {
degree = this.membershipDegree[o];
}
return degree;
}
abstract public double getMembership(final int o);
/**
* <p>
* Probabilite de la classe.
......@@ -391,9 +193,7 @@ public class Cluster implements Serializable {
*
* @return la probabilite de la classe
*/
public double getMembershipProbabilityEM() {
return this.membershipProbabilityEM;
}
abstract public double getMembershipProbabilityEM();
/**
* <p>
......@@ -442,10 +242,14 @@ public class Cluster implements Serializable {
* Locke la classe.
* </p>
*/
public void lock() {
this.locked = true;
this.data.lock();
}
abstract public void lock();
/**
* <p>
* Delocke la classe.
* </p>
*/
abstract public void unlock();
/**
* <p>
......@@ -491,18 +295,11 @@ public class Cluster implements Serializable {
this.visible = v;
}
@Override
abstract public Object clone();
@Override
public String toString() {
return this.getName();
}
/**
* <p>
* Delocke la classe.
* </p>
*/
public void unlock() {
this.locked = false;
this.data.unlock();
}
}
This diff is collapsed.
package jcl.clustering.ImageBased;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
import java.util.Vector;
import jcl.data.DataObject;
import jcl.data.attribute.AttributeNumerical;
public class CentroidFileManager {
/**
* <p>
* Methode qui permet de creer un fichier contenant les valeurs des centroides
* <p>
*
* @param filePath
* le chemin d'acces du fichier
* @param seeds
* l'ensemble des centroides a copier
*/
public static void writeCentroidFile(String filePath, Vector<DataObject> seeds) {
try{
PrintWriter writer = new PrintWriter(filePath, "UTF-8");
for (int i = 0; i < seeds.size() ; i++) {
String line = "";
for(int j = 0 ; j < seeds.get(0).getNbAttributes() ; j++) {
if (line != "") {
line += " ";
}
line += seeds.get(i).getAttribute(j).getValue();
}
writer.println(line);
}
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* <p>
* Methode qui permet de lire un fichier contenant les valeurs des centroides
* <p>
*
* @param filePath
* le chemin d'acces du fichier
* @return la liste des centroides
*/
public static Vector<DataObject> readCentroidFile(String filePath) {
Vector<DataObject> seeds = new Vector<DataObject>();
BufferedReader reader = null;
try{
reader = new BufferedReader(new FileReader(filePath));
String line = null;
while ((line = reader.readLine()) != null) {
Vector<AttributeNumerical> attributes = new Vector<AttributeNumerical>();
Scanner sc = new Scanner(line);
while(sc.hasNextDouble()) {
attributes.add(new AttributeNumerical(sc.nextDouble()));
}
DataObject obj = new DataObject(attributes.size());
for(int i = 0 ; i < attributes.size() ; i++) {
obj.setAttribute(i, attributes.get(i));
}
seeds.add(obj);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
}
}
return seeds;
}
}
package jcl.clustering.ImageBased;
import java.io.IOException;
import java.util.Vector;
import jcl.clustering.Cluster;
import jcl.clustering.ClusteringResult;
import jcl.clustering.LightCluster;
import jcl.data.DataObject;
import jcl.utils.Images.ImageReaderWrapper;
import jcl.utils.exceptions.MethodNotImplementedException;
import jcl.weights.ClassificationWeights;
import loci.formats.FormatException;
/**
* <p>
* Classe qui lit/écrit le resultat d'une classification d'une image via un fichier
* <p>
*
* @author baptistelafabregue
*
*/
public class ImagebasedClusteringResult extends ClusteringResult {
/** Chemin d'acces du fichier contenant le resultat de la classification */
private String filePath = "";
/** tableau qui contient pour chaque element d'un Data de type image son cluster de rattachement */
private byte[][] clusterMap = null;
/** non utilisé pour l'instant, mais doit pemerttre d'accéder au contenu de maniere streamee */
private int maxMemoryUsage = 0;
/** le format des pixel de l'image, correspond au formats de la classe FormatTool */
private int pixelType = 0;
/**
* <p>
* Constructeur
* <p>
*
* @param path
* le chemin d'acces du fichier contenant le resultat de la classification
* @param weights
* les ponderations utilisees
*/
public ImagebasedClusteringResult(String path, ClassificationWeights weights) {
this.filePath = path;
loadFromFile();
this.weights = weights;
this.randomColor();
}
/**
* <p>
* Constructeur
* <p>
*
* @param path
* le chemin d'acces du fichier contenant le resultat de la classification
* @param centroidsPath
* le chemin d'acces du fichier contenant la liste des centroids
* @param weights