Автоматизированная система колоризации полутонового изображения

Дипломная работа - Компьютеры, программирование

Другие дипломы по предмету Компьютеры, программирование

ментированного изображения пользователь выбирает обученную нейросеть для каждого участка, с помощью которой будет производиться колоризация выбранного участка изображения. В случае необходимости откорректировать полученные области сегментирования нужно нажать кнопку Выполнить сегментацию вручную:

Рисунок А.5 - Выполнение сегментации вручную

 

В случае выбора в пункте меню главного окна пункта Нейронная сеть появится окно редактирования параметров нейронных сетей:

 

Рисунок А.6 - Окно работы с нейронными сетями

 

В появившемся окне отображается список всех сетей, полученных в приложении. Каждую сеть можно удалить и отредактировать. Также отсюда производится создание новых сетей. Для обучения выбранной сети нужно нажать кнопку Обучить. Обучение сетей производится так же пользователем:

 

Рисунок А.7 - Обучение нейросети

 

Пользователь выбирает алгоритм обучения для сети (параметры которой, число нейронов в скрытом слое и функция активации, задал при ее создании), задает параметры обучения сети согласно выбранному алгоритму, выбирает изображения, на которых собирается обучить сеть и производит ее обучение. В ходе обучения пользователю предоставляется график ошибки обучения:

 

Рисунок А.8 - График ошибки обучения

 

Приложение 2. Листинг основных классов программы

 

В качестве алгоритма сегментации изображения был реализован алгоритм Efficient Graph-Based Image Segmentation авторов PedroF. Felzenszwalb (MIT) и DanielP. Huttenlocher (Cornell University). Для повышения производительности работы приложения было решено хранить изображение в форме одномерного вектора:

public class Image {w;h;[] data;cache;Image(BufferedImage image) {= image.getWidth();= image.getHeight();= new int[w * h]; // allocate space for image data(int i = 0; i < w * h; i++)[i] = image.getRGB(i % w, i / w);

}Image(int width, int height) {= width;= height;= new int[w * h]; // allocate space for image data

}(int i, int j) {data[j * w + i];

}void setIJ(int i, int j, intval) {[j * w + i] = val;

}

//caching buffered image for more high speed workvoid resetCache() {= null;

}() {(null == cache) {= new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);(int i = 0; i < w; i++) {(int j = 0; j < h; j++) {.setRGB(i, j, getIJ(i, j));

}

}

};

}

}

В качестве универсальной структуры работы с графами, позволяющей быстро соединять несколько графов и пересчитывать минимальные веса для решения задачи Штейнера, была выбрана структура Disjoint-setdatastructure:

public class DisjointSet {;[] elts;(int elements) {= new UniElt[elements];(int ii = 0; ii <elts.length; ii++)[ii] = new UniElt();= elements;(int i = 0; i < elements; i++) {[i].rank = 0;[i].p = i;[i].size = 1;

}

}find(int x) {y = x;(y != elts[y].p)= elts[y].p;[y].p = y;y;

}void join(int x, int y) {(elts[x].rank >elts[y].rank) {[y].p = x;[x].size += elts[y].size;

} else {[x].p = y;[y].size += elts[x].size;(elts[x].rank == elts[y].rank)

elts[y].rank++;

}

num--;

}

}

Для реализации понятия множество в алгоритме Краскала применяется структура данных Disjoint-setdatastructure. Работа с ней оптимизирована на выполнение двух основных операций: узнать для некоторой вершины, какому множеству в текущий момент она принадлежит; быстро объединить эти множества в одно.

Обучение сети производится в классах наследниках класса LearningRule:

public abstract class LearningRule extends Observable implements Runnable,{static final long serialVersionUID = 1L;NeuralNetwork neuralNetwork;transient TrainingSet trainingSet;transient volatile boolean stopLearning = false;LearningRule() {

}void setTrainingSet(TrainingSet trainingSet) {.trainingSet = trainingSet;

}TrainingSet getTrainingSet() {trainingSet;

}NeuralNetwork getNeuralNetwork() {neuralNetwork;

}void setNeuralNetwork(NeuralNetwork neuralNetwork) {.neuralNetwork = neuralNetwork;

}void run() {.learn(this.trainingSet);

}public void setStarted() {.stopLearning = false;

}public void stopLearning() {.stopLearning = true;

}public boolean isStopped() {this.stopLearning;

}void notifyChange() {();();();

}abstract void learn(TrainingSet trainingSet);

}

Каждый новый класс обучения наследуется от предыдущего, переопределяя его методы:

public class BackPropagation extends SigmoidDeltaRule {static final long serialVersionUID = 1L;BackPropagation() {();

}

@Overridevoid updateNetworkWeights(double[] patternError) {.adjustOutputNeurons(patternError);.adjustHiddenLayers();

0;i--){layer=neuralNetwork.getLayerAt(i);(Neuronneuron:layer.getNeurons()){delta=this.calculateDelta(neuron);.setError(delta);.updateNeuronWeights(neuron);">}void adjustHiddenLayers() {layerNum = this.neuralNetwork.getLayersCount();(int i = layerNum - 2; i > 0; i--) {layer = neuralNetwork.getLayerAt(i);(Neuron neuron : layer.getNeurons()) {delta = this.calculateDelta(neuron);.setError(delta);.updateNeuronWeights(neuron);

} // for

} // for

connectedTo=((Neuron)neuron).getOutConnections();delta_sum=0d;(Connectionconnection:connectedTo){d=connection.getToNeuron().getError()">}double calculateDelta(Neuron neuron) { connectedTo = ((Neuron) neuron).getOutConnections();delta_sum = 0d;(Connection connection : connectedTo) {d = connection.getToNeuron().getError()

* connection.getWeight().getValue();_sum += d; // weighted sum from the next layer

} // fortransferFunction = neuron.getTransferFunction();netInput = neuron.getNetInput();f1 = transferFunction.getDerivative(netInput);delta = f1 * delta_sum;

return delta;

}

}

Базовый класс функций активации:

public abstract class TransferFunction implements Serializable {static final long serialVersionUID = 1L;public double getOutput(double net);double getDerivative(double net) {1d;

}

@OverrideString toString() {getClass().getName();

}

}

Тангенсальная функция активации:class Tanh extends TransferFunction implements Serializable {static final long serialVersionUID = 2L;double slope = 2d;Tanh() {

}Tanh(double slope) {.slope = slope;

}Tanh(Properties properties) {{.slope = (Double) properties.getProperty("transferFunction.slope");

} catch (NullPointerException e) {new RuntimeException("properties are not set just leave default values");

} catch (NumberFormatException e) {new RuntimeException("Invalid transfer function properties! Using default values.");

}

}

@Overridepublic double getOutput(double net) {

// conditional logic helps to avoid NaN(net > 100) {1.0;

} else if (net < -100) {-1.0;

}E_x = Math.exp(this.slope * net);(E_x - 1d) / (E_x + 1d);

}

@Overridepublic double getDerivative(double net) {out = getOutput(net);(1d - out * out);

}double getSlope() {this.slope;

}void setSlope(double slope) {.slope = slope;

}

}

Класс нейросети:class NeuralNetwork extends Observable implements Runnable, Serializable {static final long serialVersionUID = 4L;NeuralNetworkType type;List();.addPlugin(new LabelsPlugin());

}void addLayer(Layer layer) {.setParent