public class HistogramClassifier {
private List<BufferedImage> ex = new ArrayList<BufferedImage>();
private List<BufferedImage> nonEx = new ArrayList<BufferedImage>();
private int exSize;
private int nonExSize;
private Histogram[] exHist;
private Histogram[] nonExHist;
private double[][] avg1, avg2;
private Result result;
private Result result2;
private double[] eucl1, eucl2;
/**
* @param input
*/
public HistogramClassifier() {
}
/**
* @param ex
* @param nonEx
*/
public void train() {
readFiles(new File("/Users/Desktop"));
this.exSize = ex.size();
this.nonExSize = nonEx.size();
exHist = new Histogram[exSize];
nonExHist = new Histogram[nonExSize];
try{
for(int i = 0; i < ex.size(); i++){
exHist[i] = new Histogram(ex.get(i));
}
for(int i = 0; i < nonEx.size(); i++){
nonExHist[i] = new Histogram(nonEx.get(i));
}
}catch(Exception e){
e.printStackTrace();
}
avg1 = calculateAverage(exHist);
avg2 = calculateAverage(nonExHist);
eucl1 = (exHist);
eucl2 = calculateEuclideanDistance(nonExHist);
}
/**
* @param exHist
* @return
*/
private double[][] calculateAverage(Histogram[] hist) {
double[][] avg = new double[3][256];
int length = hist.length;
// store the sum of each image's frequency in each band
for(int i = 0; i < length; i++){
for(int b = 0; b < 3; b++){
for(int f = 0; f < 256; f++){
avg[b][f] += hist[i].getFrequency(b, f);
}
}
}
// divide each frequency in the average by the #samples in the class
for(int b = 0; b < 3; b++){
for(int f = 0; f < 256; f++){
avg[b][f] /= length;
}
}
return avg;
}
/**
* @param input
*/
public void classify(List<BufferedImage> input) {
Histogram[] test = new Histogram[input.size()];
try{
for(int i = 0; i < input.size(); i++){
test[i] = new Histogram(input.get(i));
}
}catch(Exception e){
e.printStackTrace();
}
double[] dist1 = calculateDistances(test, avg1);
double[] dist2 = calculateDistances(test, avg2);
result = Result.NONEXUDATE;
int numOfEx = 0;
for(int i = 0; i < input.size(); i++){
//System.out.println(i + " Dist1, Dist2 \t\t\t" + dist1[i] + "," + dist2[i]);
if(dist1[i] < dist2[i]){
result = Result.EXUDATE;
numOfEx++;
}
}
double ratio = (double)numOfEx / input.size();
System.out.println("Number of test samples: " + input.size());
System.out.println("Number of classified exudate: " + numOfEx);
System.out.println("Histogram classifier result: " + result
+ "\nRatio of exudate: " + ratio);
//System.out.printIn("Euclidean Distance: " + )
}
/**
* @param test
* @param avg
* @return
*/
private double[] calculateDistances(Histogram[] test, double[][] avg) {
int length = test.length;
double dist[] = new double[length];
for(int i = 0; i < length; i++){
double[] d = new double[3];
for(int b = 0; b < 3; b++){
for(int f = 0; f < 256; f++){
d[b] += Math.pow((test[i].getFrequency(b, f) - avg[b][f]), 2);
}
}
for(double v : d){
dist[i] += v;
}
}
return dist;
}
private double[] calculateEuclideanDistance(Histogram[]eucl, Histogram[]exHist){
int length = eucl.length;
double edist[] = new double [length];
for(int b = 0; b < 3; b++){
for (int s = 0; s<256; s++) {
edist += Math.pow(Math.abs(eucl[b][s] - exHist[b][s], 2.0));
}
}
return Math.sqrt(edist);
}
/**
*
*/
private void readFiles(File dir) {
for(File file : dir.listFiles()){
String name = file.getName();
if(file.isDirectory() && (name.equals("Ex") || name.equals("NonEx"))){
try {
addFiles(file, name);
}catch(Exception e){
e.printStackTrace();
}
}else if(file.isDirectory()){
readFiles(file);
}
}
}
/**
* @param file
* @return
* @throws ImageDecoderException
* @throws IOException
*/
private void addFiles(File file, String dir) throws IOException, ImageDecoderException {
for(File image : file.listFiles()){
String path = image.getPath();
if(path.contains(".jpg")){
ImageDecoder input = ImageFile.createImageDecoder(path);
if(dir.equals("Ex") && path.contains("Color")){
ex.add(input.decodeAsBufferedImage());
}else if(dir.equals("NonEx") && path.contains("Color")){
nonEx.add(input.decodeAsBufferedImage());
}
}
}
}
}