/**
* Copyright 2010 Neuroph Project http://neuroph.sourceforge.net
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.neuroph.imgrec;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.StringTokenizer;
import javax.imageio.ImageIO;
import org.neuroph.core.NeuralNetwork;
import org.neuroph.core.Neuron;
import org.neuroph.core.data.DataSet;
import org.neuroph.core.data.DataSetRow;
import org.neuroph.core.exceptions.VectorSizeMismatchException;
import org.neuroph.imgrec.image.Dimension;
import org.neuroph.imgrec.image.Image;
import org.neuroph.imgrec.image.ImageFactory;
import org.neuroph.nnet.MultiLayerPerceptron;
import org.neuroph.nnet.learning.MomentumBackpropagation;
import org.neuroph.util.TransferFunctionType;
import org.neuroph.util.plugins.PluginBase;
/**
* Provides methods to create neural network and training set for image recognition.
* This class is mostly based on the code from tileclassification utility by Jon Tait
* @author Jon Tait
* @author Zoran Sevarac
*/
public class ImageRecognitionHelper {
/**
* Creates and returns new neural network for image recognition.
* Assumes that all of the FractionRgbData objects in the given map have identical
* length arrays in them so that the input layer of the neural network can be
* created here.
*
* @param label neural network label
* @param samplingResolution sampling resolution (image size)
* @param imageLabels image labels
* @param layersNeuronsCount neuron counts in hidden layers
* @param transferFunctionType type of transfer function to use for neurons in network
* @param colorMode color mode
* @return
*/
public static NeuralNetwork createNewNeuralNetwork(String label, Dimension samplingResolution, ColorMode colorMode, List imageLabels, List layersNeuronsCount, TransferFunctionType transferFunctionType) {
int numberOfInputNeurons;
if ((colorMode == ColorMode.COLOR_RGB) || (colorMode == ColorMode.COLOR_HSL) ){ // for full color rgb or hsl
numberOfInputNeurons = 3 * samplingResolution.getWidth() * samplingResolution.getHeight();
} else { // for black n white network
numberOfInputNeurons = samplingResolution.getWidth() * samplingResolution.getHeight();
}
int numberOfOuputNeurons = imageLabels.size();
layersNeuronsCount.add(0, numberOfInputNeurons);
layersNeuronsCount.add(numberOfOuputNeurons);
System.out.println("Neuron layer size counts vector = " + layersNeuronsCount);
NeuralNetwork neuralNetwork = new MultiLayerPerceptron(layersNeuronsCount, transferFunctionType);
neuralNetwork.setLabel(label);
PluginBase imageRecognitionPlugin = new ImageRecognitionPlugin(samplingResolution, colorMode);
neuralNetwork.addPlugin(imageRecognitionPlugin);
assignLabelsToOutputNeurons(neuralNetwork, imageLabels);
neuralNetwork.setLearningRule(new MomentumBackpropagation());
return neuralNetwork;
}
/**
* Assign labels to output neurons
* @param neuralNetwork neural network
* @param imageLabels image labels
*/
private static void assignLabelsToOutputNeurons(NeuralNetwork neuralNetwork, List imageLabels) {
List outputNeurons = neuralNetwork.getOutputNeurons();
for(int i=0; i imageLabels, Map rgbDataMap) {
return createRGBTrainingSet(imageLabels, rgbDataMap);
}
/**
* Creates training set for the specified image labels and rgb data
* @param imageLabels image labels
* @param rgbDataMap map collection of rgb data
* @return training set for the specified image data
*/
public static DataSet createRGBTrainingSet(List imageLabels, Map rgbDataMap) {
int inputCount = rgbDataMap.values().iterator().next().getFlattenedRgbValues().length;
int outputCount = imageLabels.size();
DataSet trainingSet = new DataSet(inputCount, outputCount);
for (Entry entry : rgbDataMap.entrySet()) {
double[] input = entry.getValue().getFlattenedRgbValues();
double[] response = createResponse(entry.getKey(), imageLabels);
trainingSet.addRow(new DataSetRow(input, response));
}
// set labels for output columns
int inputSize = trainingSet.getInputSize();
for (int c= 0; c imageLabels, Map hslDataMap) {
int inputCount = hslDataMap.values().iterator().next().getFlattenedHSLValues().length;
int outputCount = imageLabels.size();
DataSet trainingSet = new DataSet(inputCount, outputCount);
for (Entry entry : hslDataMap.entrySet()) {
double[] input = entry.getValue().getFlattenedHSLValues();
double[] response = createResponse(entry.getKey(), imageLabels);
trainingSet.addRow(new DataSetRow(input, response));
}
// set labels for output columns
int inputSize = trainingSet.getInputSize();
for (int c= 0; c imageLabels, Map rgbDataMap) throws VectorSizeMismatchException
{
// TODO: Use some binarization image filter to do this; currently it works with averaging RGB values
int inputCount = rgbDataMap.values().iterator().next().getFlattenedRgbValues().length / 3;
int outputCount = imageLabels.size();
DataSet trainingSet = new DataSet(inputCount, outputCount);
for (Entry entry : rgbDataMap.entrySet()) {
double[] inputRGB = entry.getValue().getFlattenedRgbValues();
double[] inputBW = FractionRgbData.convertRgbInputToBinaryBlackAndWhite(inputRGB);
double[] response = createResponse(entry.getKey(), imageLabels);
trainingSet.addRow(new DataSetRow(inputBW, response));
}
// set labels for output columns
int inputSize = trainingSet.getInputSize();
for (int c= 0; c getFractionRgbDataForDirectory(File imgDir, Dimension samplingResolution) throws IOException
{
if(!imgDir.isDirectory()) {
throw new IllegalArgumentException("The given file must be a directory. Argument is: " + imgDir);
}
Map rgbDataMap = new HashMap<>();
ImageFilesIterator imagesIterator = new ImageFilesIterator(imgDir);
while (imagesIterator.hasNext()) {
File imgFile = imagesIterator.next();
Image img = ImageFactory.getImage(imgFile);
img = ImageSampler.downSampleImage(samplingResolution, img);
String filenameOfCurrentImage = imagesIterator.getFilenameOfCurrentImage();
StringTokenizer st = new StringTokenizer(filenameOfCurrentImage, ".");
rgbDataMap.put(st.nextToken(), new FractionRgbData(img));
}
return rgbDataMap;
}
// creates hsl map from given image files - params should be files List - or even better image files
public static Map getFractionHSLDataForDirectory ( File imgDir, Dimension samplingResolution) throws IOException {
if(!imgDir.isDirectory()) {
throw new IllegalArgumentException("The given file must be a directory. Argument is: " + imgDir);
}
Map map = new HashMap<>();
ImageFilesIterator imagesIterator = new ImageFilesIterator(imgDir);
try {
while (imagesIterator.hasNext()) {
File imgFile = imagesIterator.next();
BufferedImage img = ImageIO.read(imgFile);
BufferedImage image = ImageUtilities.resizeImage(img, samplingResolution.getWidth(), samplingResolution.getHeight());
String filenameOfCurrentImage = imgFile.getName();
//String filenameOfCurrentImage = imagesIterator.getFilenameOfCurrentImage();
StringTokenizer st = new StringTokenizer(filenameOfCurrentImage, ".");
map.put(st.nextToken(), new FractionHSLData(image));
}
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
/**
* Creates binary network output vector (response) for the specified list of images
* Each network output (neuron) corresponds to one image.
* @param inputLabel label of the input image
* @param imageLabels labels used for output neurons
* @return network response for the specified input
*/
private static double[] createResponse(String inputLabel, List imageLabels)
{
double[] response = new double[imageLabels.size()];
int i=0;
for(String imageLabel : imageLabels) {
if(inputLabel.startsWith(imageLabel)) {
response[i] = 1d;
} else {
response[i] = 0d;
}
i++;
}
return response;
}
private static List createLabels(HashMap map)
{
List imageLabels = new ArrayList();
for (String imgName : map.keySet()) {
StringTokenizer st = new StringTokenizer(imgName, "._");
String imageLabel = st.nextToken();
if (!imageLabels.contains(imageLabel)) {
imageLabels.add(imageLabel);
}
}
Collections.sort(imageLabels);
return imageLabels;
}
public static DataSet createImageDataSetFromFile(String imageDir, List imageLabels, String junkDir, ColorMode colorMode, Dimension samplingResolution, String trainingSetName, int numOfPictures)
{
DataSet dataSet = null;
HashMap rgbDataMap = new HashMap<>();
HashMap hslDataMap = new HashMap<>();
// load color infor for images to recognize
try {
// load images and get/set labels for all images
File labeledImagesDir = new File(imageDir);
if (colorMode == ColorMode.COLOR_HSL) {
hslDataMap.putAll(ImageRecognitionHelper.getFractionHSLDataForDirectory(labeledImagesDir, samplingResolution));
if (imageLabels == null) imageLabels = createLabels(hslDataMap);
} else {
rgbDataMap.putAll(ImageRecognitionHelper.getFractionRgbDataForDirectory(labeledImagesDir, samplingResolution)); // pre je koristio ImageLoader
if (imageLabels == null) imageLabels = createLabels(rgbDataMap);
}
} catch (IOException ioe) {
System.err.println("Unable to load images from labeled images dir: '" + imageDir + "'");
System.err.println(ioe.toString());
}
// load junk images
if ((junkDir != null) && (!junkDir.equals(""))) {
try {
File junkImagesDir = new File(junkDir);
if (colorMode == ColorMode.COLOR_HSL) {
hslDataMap.putAll(ImageRecognitionHelper.getFractionHSLDataForDirectory(junkImagesDir, samplingResolution));
} else
rgbDataMap.putAll(ImageRecognitionHelper.getFractionRgbDataForDirectory(junkImagesDir, samplingResolution)); // pre je koristio ImageLoader
} catch (IOException ioe) {
System.err.println("Unable to load images from junk images dir: '" + junkDir + "'");
System.err.println(ioe.toString());
}
}
// create data set
if (colorMode == ColorMode.COLOR_RGB) {
dataSet = ImageRecognitionHelper.createRGBTrainingSet(imageLabels, rgbDataMap);
} else if (colorMode == ColorMode.COLOR_HSL) {
dataSet = ImageRecognitionHelper.createHSLTrainingSet(imageLabels, hslDataMap);
} else {
dataSet = ImageRecognitionHelper.createBlackAndWhiteTrainingSet(imageLabels, rgbDataMap);
}
dataSet.setLabel(trainingSetName);
dataSet.setColumnNames((String[]) imageLabels.toArray());//TODO: setOutputNames()
dataSet.save("D:\\Doktorske\\Beograd\\Neuronske mreze - Zoran Sevarac\\Cifar 10\\dataset.tset");
return dataSet;
}
}
Ads help maintain this website.