-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
253 additions
and
0 deletions.
There are no files selected for viewing
79 changes: 79 additions & 0 deletions
79
src/main/groovy/net/zomis/machlearn/images/ImageAnalysis.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package net.zomis.machlearn.images; | ||
|
||
import java.awt.image.BufferedImage; | ||
|
||
public class ImageAnalysis { | ||
|
||
private final int width; | ||
private final int height; | ||
private final boolean useGrayscale; | ||
|
||
public ImageAnalysis(int width, int height, boolean useGrayscale) { | ||
this.width = width; | ||
this.height = height; | ||
this.useGrayscale = useGrayscale; | ||
} | ||
|
||
public ImageNetworkBuilder neuralNetwork(int... hiddenLayerSizes) { | ||
return new ImageNetworkBuilder(width * height * partsPerPixel(), hiddenLayerSizes); | ||
} | ||
|
||
public double[] imagePart(BufferedImage image, int x, int y) { | ||
return imagePart(image, x, y, width, height, useGrayscale); | ||
} | ||
|
||
public static double[] imagePart(BufferedImage image, int x, int y, int width, int height, boolean useGrayscale) { | ||
int partsPerPixel = useGrayscale ? 1 : 3; | ||
double[] result = new double[width * height * partsPerPixel]; | ||
int i = 0; | ||
for (int yy = y; yy < y + height; yy++) { | ||
for (int xx = x; xx < x + width; xx++) { | ||
double[] rgbGray = getRGB(image, xx, yy); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
Zomis
Author
Owner
|
||
if (useGrayscale) { | ||
result[i++] = rgbGray[3]; | ||
} else { | ||
result[i++] = rgbGray[0]; | ||
result[i++] = rgbGray[1]; | ||
result[i++] = rgbGray[2]; | ||
} | ||
} | ||
} | ||
return result; | ||
} | ||
|
||
private int partsPerPixel() { | ||
return useGrayscale ? 1 : 3; | ||
} | ||
|
||
public SlidingWindow slidingWindow(ImageNetwork network, BufferedImage image) { | ||
return new SlidingWindow(network, image); | ||
} | ||
|
||
/** | ||
* Returns the color of a pixel | ||
* | ||
* @param image The image to get the pixel from | ||
* @param x X coordinate | ||
* @param y Y coordinate | ||
* @return An array of Alpha, Red, Green, Blue, and Gray-scale | ||
*/ | ||
public static double[] getRGB(BufferedImage image, int x, int y) { | ||
if (x < 0) { | ||
x = image.getWidth() + x; | ||
} | ||
if (y < 0) { | ||
y = image.getHeight() + y; | ||
} | ||
int rgb = image.getRGB(x, y); | ||
int a = (rgb >> 24) & 0xFF; | ||
int r = (rgb >> 16) & 0xFF; | ||
int g = (rgb >> 8) & 0xFF; | ||
int b = rgb & 0xFF; | ||
double gray = 0.2989 * r + 0.5870 * g + 0.1140 * b; | ||
return new double[] { a / 255d, r / 255d, g / 255d, b / 255d, gray / 255d }; | ||
} | ||
|
||
public void image(BufferedImage image) { | ||
|
||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
src/main/groovy/net/zomis/machlearn/images/ImageNetwork.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package net.zomis.machlearn.images; | ||
|
||
import net.zomis.machlearn.neural.NeuralNetwork; | ||
|
||
import java.util.Arrays; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
public class ImageNetwork { | ||
|
||
private final NeuralNetwork network; | ||
private final Object[] outputs; | ||
|
||
public ImageNetwork(NeuralNetwork network, Object[] outputs) { | ||
if (network.getOutputLayer().size() != outputs.length) { | ||
throw new IllegalArgumentException( | ||
String.format("Network output layer (%d) does not match object array length (%d)", | ||
network.getOutputLayer().size(), outputs.length)); | ||
} | ||
this.network = network; | ||
this.outputs = Arrays.copyOf(outputs, outputs.length); | ||
} | ||
|
||
public Object[] getOutputs() { | ||
return Arrays.copyOf(outputs, outputs.length); | ||
} | ||
|
||
public Map<Object, Double> run(double[] imageData) { | ||
double[] outputs = network.run(imageData); | ||
System.out.println(Arrays.toString(outputs)); | ||
Map<Object, Double> result = new HashMap<>(); | ||
for (int i = 0; i < outputs.length; i++) { | ||
result.put(this.outputs[i], outputs[i]); | ||
} | ||
return result; | ||
} | ||
|
||
public NeuralNetwork getNetwork() { | ||
return this.network; | ||
} | ||
|
||
} |
75 changes: 75 additions & 0 deletions
75
src/main/groovy/net/zomis/machlearn/images/ImageNetworkBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package net.zomis.machlearn.images; | ||
|
||
import net.zomis.machlearn.neural.BackPropagation; | ||
import net.zomis.machlearn.neural.LearningData; | ||
import net.zomis.machlearn.neural.NeuralNetwork; | ||
import net.zomis.machlearn.neural.NeuronLayer; | ||
|
||
import java.util.*; | ||
import java.util.stream.Collectors; | ||
|
||
public class ImageNetworkBuilder { | ||
|
||
private final NeuralNetwork network; | ||
private final Map<Object, List<double[]>> classifications = new HashMap<>(); | ||
|
||
public ImageNetworkBuilder(int inputSize, int... hiddenLayerSizes) { | ||
this.network = new NeuralNetwork(); | ||
NeuronLayer layer = this.network.createLayer("INPUT"); | ||
for (int i = 0; i < inputSize; i++) { | ||
layer.createNeuron(); | ||
} | ||
|
||
int hiddenIndex = 1; | ||
for (int layerSize : hiddenLayerSizes) { | ||
NeuronLayer parentLayer = layer; | ||
layer = this.network.createLayer("HIDDEN " + (hiddenIndex++)); | ||
for (int i = 0; i < layerSize; i++) { | ||
layer.createNeuron().addInputs(parentLayer); | ||
} | ||
} | ||
} | ||
|
||
public ImageNetworkBuilder classify(Object result, double[] input) { | ||
classifications.putIfAbsent(result, new ArrayList<>()); | ||
classifications.get(result).add(Arrays.copyOf(input, input.length)); | ||
return this; | ||
} | ||
|
||
public ImageNetwork learn() { | ||
int outputNodes = classifications.size() - 1; | ||
|
||
NeuronLayer parentLayer = this.network.getLastLayer(); | ||
NeuronLayer layer = this.network.createLayer("OUTPUT"); | ||
for (int i = 0; i < outputNodes; i++) { | ||
layer.createNeuron().addInputs(parentLayer); | ||
} | ||
|
||
List<LearningData> learningData = new ArrayList<>(); | ||
int outputIndex = 0; | ||
Object[] objects = new Object[outputNodes]; | ||
for (Map.Entry<Object, List<double[]>> entry : classifications.entrySet()) { | ||
double[] outputs = new double[outputNodes]; | ||
if (entry.getKey() != null) { | ||
outputs[outputIndex] = 1; | ||
objects[outputIndex] = entry.getKey(); | ||
outputIndex++; | ||
} | ||
learningData.addAll(entry.getValue().stream() | ||
.map(inputs -> new LearningData(inputs, outputs)) | ||
.collect(Collectors.toList())); | ||
} | ||
BackPropagation backprop = new BackPropagation(0.5, 100); | ||
backprop.setLogRate(10); | ||
backprop.backPropagationLearning(learningData, network); | ||
|
||
return new ImageNetwork(network, objects); | ||
} | ||
|
||
public ImageNetworkBuilder classifyNone(double[] input) { | ||
classifications.putIfAbsent(null, new ArrayList<>()); | ||
classifications.get(null).add(Arrays.copyOf(input, input.length)); | ||
return this; | ||
} | ||
|
||
} |
40 changes: 40 additions & 0 deletions
40
src/main/groovy/net/zomis/machlearn/images/SlidingWindow.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package net.zomis.machlearn.images; | ||
|
||
import java.awt.image.BufferedImage; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class SlidingWindow { | ||
|
||
private final ImageNetwork network; | ||
private final BufferedImage image; | ||
private int minScaleX; | ||
private int maxScaleX; | ||
private int step; | ||
private boolean overlapping; | ||
|
||
public SlidingWindow(ImageNetwork network, BufferedImage image) { | ||
this.network = network; | ||
this.image = image; | ||
} | ||
|
||
public SlidingWindow scaleX(int min, int max) { | ||
this.minScaleX = min; | ||
this.maxScaleX = max; | ||
return this; | ||
} | ||
|
||
public SlidingWindow step(int stepSize) { | ||
this.step = stepSize; | ||
return this; | ||
} | ||
|
||
public SlidingWindowResult run() { | ||
return null; | ||
} | ||
|
||
public SlidingWindow overlapping(boolean b) { | ||
this.overlapping = b; | ||
return this; | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/groovy/net/zomis/machlearn/images/SlidingWindowResult.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package net.zomis.machlearn.images; | ||
|
||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
public class SlidingWindowResult { | ||
|
||
Map<ZPoint, Set<Object>> points; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package net.zomis.machlearn.images; | ||
|
||
public class ZPoint { | ||
|
||
int x, y; | ||
|
||
} |
If you are concerned about performance at this point, then I'd suggest you to read http://stackoverflow.com/a/9470843/2057294 to learn more about
BufferedImage#getRGB(int x, int y)
.