You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
116 lines
4.4 KiB
Java
116 lines
4.4 KiB
Java
package mosaic.picture.worker;
|
|
|
|
import java.awt.Color;
|
|
import java.awt.Dimension;
|
|
import java.awt.image.BufferedImage;
|
|
import java.awt.image.ColorModel;
|
|
import java.io.File;
|
|
import java.util.HashMap;
|
|
|
|
import mosaic.log.Log;
|
|
import mosaic.log.LogLevel;
|
|
import mosaic.picture.ImageAnalyzer;
|
|
import mosaic.picture.ImageUtils;
|
|
|
|
public class TargetImageAnalyzerWorker extends ImageAnalyzerWorker{
|
|
|
|
private ImageAnalyzer ia;
|
|
private int startCoord, endCoord;
|
|
|
|
/**
|
|
*
|
|
* @param ia ImageAnalyzer to work for
|
|
* @param name Thread name to use (should be unique)
|
|
* @param img Image to work on
|
|
* @param startCoord slot x coordinate to start from
|
|
* @param endCoord slot y coordinate to start from
|
|
*/
|
|
public TargetImageAnalyzerWorker(ImageAnalyzer ia, String name, int startCoord, int endCoord){
|
|
super(ia, name);
|
|
this.ia = ia;
|
|
this.startCoord = startCoord;
|
|
this.endCoord = endCoord;
|
|
|
|
this.start();
|
|
}
|
|
|
|
public void run(){
|
|
Log.log(LogLevel.Info, "Worker "+this.getName()+" up and running! Let's roll ...");
|
|
HashMap<int[], Integer> result = this.classifyArea(startCoord, endCoord);
|
|
ia.addSlotClassifications(result, this.getName());
|
|
Log.log(LogLevel.Info, "Worker "+this.getName()+" finished work! Terminating ...");
|
|
}
|
|
|
|
/**
|
|
* Classifies the specified Area of the target image and returns the average colors.
|
|
*
|
|
* Returns a HashMap with the slot coordinates (slot) as key.
|
|
* @param startCoord slotX to start in
|
|
* @param endCoord slotY to start in
|
|
* @param workArea number of slots to work through
|
|
* @param target image to work on
|
|
*/
|
|
public HashMap<int[], Integer> classifyArea(int startCoord, int endCoord){
|
|
BufferedImage target = ia.target;
|
|
HashMap<int[], Integer> results = new HashMap<int[], Integer>();
|
|
Log.log(LogLevel.Debug, "["+this.getName()+"] Was ordered to classify "+startCoord+" "+endCoord);
|
|
for(int i = startCoord; i < endCoord; i++){
|
|
int[] coordPixels = ImageUtils.getSlotCoordPixels(ia, ImageUtils.getSlotCoord(ia, i), true);
|
|
if(coordPixels[0]+ia.preSlotWidth >= ia.target.getWidth() || coordPixels[1]+ia.preSlotHeight >= ia.target.getHeight()){
|
|
//Dirty FIX
|
|
//This will inevitably land outside the Raster otherwise. I should prevent these Coords from the start
|
|
//Log.log(LogLevel.Error, "Didn't classify "+coordPixels[0]+" "+coordPixels[1]);
|
|
continue;
|
|
}
|
|
int rgb = classifySlot(coordPixels[0], coordPixels[1], ia.preSlotWidth, ia.preSlotHeight, ia.target);
|
|
int[] coordSlot = {coordPixels[0]/ia.preSlotWidth, coordPixels[1]/ia.preSlotHeight};
|
|
Log.log(LogLevel.Debug, "["+this.getName()+"] Classified on slot "+coordSlot[0]+" "+coordSlot[1]+" i:"+i
|
|
+" coordPixels:"+coordPixels[0]+"x"+coordPixels[1]+" preslotDimensions:"+ia.preSlotWidth+"x"+ia.preSlotHeight+
|
|
" slotX:"+ia.slotX+" slotY:"+ia.slotY);
|
|
/*if(coordPixels[0] == 210 && coordPixels[1] == 0){//TODO remove
|
|
System.out.println("Brrrring!");
|
|
Log.log(LogLevel.Error, "Brrrriiing"+rgb+" ");
|
|
System.out.println(rgb);
|
|
System.out.println(coordSlot[0]+" "+coordSlot[1]);
|
|
}*/
|
|
|
|
results.put(coordSlot, rgb);
|
|
}
|
|
return results;
|
|
}
|
|
|
|
/**
|
|
* Classifies a single specified slot on the given Image.
|
|
* @param gridX Slot specification in X
|
|
* @param gridY Slot specification in Y
|
|
* @param slotWidth Slot size in x direction
|
|
* @param slotHeight Slot size in y direction
|
|
* @param target Image to work on
|
|
* @return average Color as RGB value
|
|
*/
|
|
public int classifySlot(int gridX, int gridY, int slotWidth, int slotHeight, BufferedImage target){
|
|
Log.log(LogLevel.Debug, "["+this.getName()+"] Slicing slot at pixels: "+gridX+"x"+gridY+" out of the target with "+slotWidth+"x"+slotHeight+"for classification ...");
|
|
BufferedImage subImage = target.getSubimage(gridX, gridY, slotWidth, slotHeight);
|
|
ColorModel cm = ColorModel.getRGBdefault();
|
|
float red = 0, green = 0, blue = 0;
|
|
int pixels = 0;
|
|
for(int x = 0; x < subImage.getWidth(); x++){
|
|
for(int y = 0; y < subImage.getHeight(); y++){
|
|
int rgb = subImage.getRGB(x, y);
|
|
red += cm.getRed(rgb);
|
|
green += cm.getGreen(rgb);
|
|
blue += cm.getBlue(rgb);
|
|
pixels++;
|
|
}
|
|
}
|
|
red = red/pixels;
|
|
green = green/pixels;
|
|
blue = blue/pixels;
|
|
int rgb = new Color((int)red, (int)green, (int)blue).getRGB();
|
|
Log.log(LogLevel.Debug, "["+this.getName()+"] Classified slot at pixels: "+gridX+"x"+gridY+" with following rgb result: value:"+rgb+
|
|
" red:"+red+", green:"+green+", blue:"+blue);
|
|
return rgb;
|
|
}
|
|
|
|
}
|