/// <summary> /// Genera un input valido para la SOM /// </summary> /// <param name="pattern">Patron a partir del cual se genera el input</param> /// <returns>Input</returns> private double[] generateInput(Pattern pattern) { return pattern.ToList().Select(x => (double)x).ToArray(); }
/// <summary> /// Extrae el patrón de una imagen, con la cantidad de componentes igual a la cantidad de neuronas en la red. /// </summary> /// <param name="sourceBitmap">Imagen a partir de la cual se extrae el patrón</param> /// <param name="activationValue">Valor utilizado para establer si un pixel es orientado o no en la matriz de pesos</param> /// <param name="outBitmap">Imagen resultante a partir de la cual se extrajo el patron</param> protected virtual Pattern patternFromBitmap(Bitmap sourceBitmap, float threshold, out Bitmap outBitmap) { //El patron esta formado por un conjunto de estados de las neuronas Pattern pattern = new Pattern((double)InputSize); //Escala la imagen para que tenga tanto pixeles como neuronas y la pasa a blanco y negro sourceBitmap = ImageAPI.ResizeBitmap(sourceBitmap, SqrtInputSize, SqrtInputSize); sourceBitmap = ImageAPI.BitmapToMonochrome(sourceBitmap, threshold); //Establece los estados de las neuronas para cada pixel for (int i = 0; i < SqrtInputSize; i++) { for (int j = 0; j < SqrtInputSize; j++) //La matriz es cuadrada { int pixelValue = Math.Abs(sourceBitmap.GetPixel(i, j).ToArgb()); if (pixelValue == 1) { sourceBitmap.SetPixel(i, j, Color.White); pattern[i, j] = 0; } else { sourceBitmap.SetPixel(i, j, Color.Black); pattern[i, j] = 1; } } } outBitmap = sourceBitmap; return pattern; }
/// <summary> /// Clasifica un patron devolviendo el numero de neurona mas cercano (menor distancia) /// </summary> /// <param name="pattern">Patron a clasificar</param> /// <returns>Numero de neurona representante de una clase</returns> private int classifyPattern(Pattern pattern) { // Computa el patorn en la red y solicita la neurona ganadora somNN.Compute(generateInput(pattern)); return somNN.GetWinner(); }
/// <summary> /// Genera el patrón a través del metodo habitual. /// </summary> /// <param name="sourceImage">Imagen a partir de la cual se generara el patrón</param> /// <param name="pattern">Patrón resultante</param> /// <param name="patternHash">Hash que identifica unívocamente este patrón</param> protected virtual void generatePattern_Normal(Image sourceImage, out Pattern pattern, out string patternHash) { //Convierte la imagen a bitmap Bitmap sourceBitmap = ImageAPI.AlltoBMP(sourceImage); //Extrae el patron y su bitmap Bitmap processedBitmap; pattern = patternFromBitmap(sourceBitmap, Threshold, out processedBitmap); //Genera el hash a partir del bitmap de salida patternHash = ImageAPI.GenerateSHA1HashFromImage(processedBitmap); return; }
/// <summary> /// Convierte un bithash a un patrón. La cantidad de bits debe coincidir con la cantidad de neuronas. /// </summary> /// <param name="sourceBitmap">Bithash a partir de la cual se extrae el patrón</param> /// <param name="outBitmap">Imagen resultante a partir de la cual se extrajo el patron</param> protected virtual Pattern patternFromBithash(BitArray bithash, out Bitmap outBitmap) { //Valida la cantidad de bits iniciales if (bithash.Count < InputSize) { outBitmap = null; return null; } //El patron esta formado por un conjunto de estados de las neuronas Pattern pattern = new Pattern((double)InputSize); //Crea el bitmap que se devolvera Bitmap processedBitmap = new Bitmap(SqrtInputSize, SqrtInputSize); //Establece los estados de las neuronas para cada bit for (int i = 0; i < InputSize; i++) { if (bithash.Get(i)) { processedBitmap.SetPixel(i / SqrtInputSize, i % SqrtInputSize, Color.Black); pattern[i] = 1; } else { processedBitmap.SetPixel(i / SqrtInputSize, i % SqrtInputSize, Color.White); pattern[i] = 0; } } outBitmap = processedBitmap; return pattern; }
/// <summary> /// Genera el patrón a través del metodo de hashing, aumentando la ortoganalidad de los patrones generados /// pero limitando el reconocimiento a patrones idénticos. /// </summary> /// <param name="sourceImage">Imagen a partir de la cual se generara el patrón</param> /// <param name="pattern">Patrón resultante</param> /// <param name="patternHash">Hash que identifica unívocamente este patrón</param> protected virtual void generatePattern_Hashing(Image sourceImage, out Pattern pattern, out string patternHash) { //Extrae un hash de tantos bits como neuronas a partir de la imagen BitArray bitHash = ImageAPI.GenerateBitHashFromImage(sourceImage, InputSize); //Extrae el patron y su bitmap Bitmap processedBitmap; pattern = patternFromBithash(bitHash, out processedBitmap); //Genera el hash a partir del bitmap de salida patternHash = ImageAPI.GenerateSHA1HashFromImage(processedBitmap); return; }
/// <summary> /// Genera el patrón a través del metodo habitual, y luego crea el heightmap del patron generado. /// </summary> /// <param name="sourceImage">Imagen a partir de la cual se generara el patrón</param> /// <param name="pattern">Patrón resultante</param> /// <param name="heightmap">Heightmap del patrón generado</param> /// <param name="patternHash">Hash que identifica unívocamente este patrón</param> protected virtual void generatePattern_Heightmap(Image sourceImage, out Pattern pattern, out List<double> heightmap, out string patternHash) { generatePattern_Normal(sourceImage, out pattern, out patternHash); heightmap = calculateHeightmap(bitmapFromPattern(pattern)); return; }
/// <summary> /// Crea un bitmap a partir de un patrón. Esta será una imagen monocromo. /// </summary> /// <param name="pattern">Patrón utilizado para generar el bitmap</param> protected virtual Bitmap bitmapFromPattern(Pattern pattern) { Bitmap resultBitmap = new Bitmap(SqrtInputSize, SqrtInputSize); for (int i = 0; i < resultBitmap.Width; i++) { for (int j = 0; j < resultBitmap.Height; j++) { if (pattern[i, j] == 1) { resultBitmap.SetPixel(i, j, Color.Black); } else { resultBitmap.SetPixel(i, j, Color.White); } } } return resultBitmap; }
/// <summary> /// Enseña un patron a la red. /// </summary> /// <param name="pattern">Patron a aprender</param> private void teachPattern(Pattern pattern) { var neuronPattern = patternToNeurons(pattern); hopfieldNN.AddPattern(neuronPattern); }
/// <summary> /// Diagnostica un patrón tantas veces como iteraciones se especifiquen. /// Devuelve el patrón resultante. /// </summary> /// <param name="inPattern">Patrón inicial</param> /// <param name="heightmap">Heightmap utilizado para el diagnostico, puede ser null</param> private Pattern recognizePattern(Pattern inPattern, List<double> heightmap) { bool heightmapMethod = Method == GenerationMethod.Heightmap; List<Neuron> outputNeurons = patternToNeurons(inPattern); List<Neuron> currentState; do { hopfieldNN.Run(outputNeurons, heightmap, UpdSequence); currentState = hopfieldNN.Neurons; if (heightmapMethod && currentState == outputNeurons) break; else outputNeurons = currentState; } while (heightmapMethod); return neuronsToPattern(outputNeurons); }
/// <summary> /// Realiza el pasaje del patron grafico a su interpretacion valida para la NNA de Hopfield /// </summary> /// <param name="pattern">Patron grafico</param> /// <returns>Patron neuronal valido para hopfield</returns> private List<Neuron> patternToNeurons(Pattern pattern) { var result = new List<Neuron>(); for(int i = 0; i < pattern.Count; i++) { var neuron = new Neuron(); neuron.State = pattern[i] == 1 ? NeuronStates.AgainstField : NeuronStates.AlongField; result.Add(neuron); } return result; }
/// <summary> /// Realiza el pasaje del patron neuronal de hopfield a su equivalente grafica monocromatica /// </summary> /// <param name="neurons">Patron neuronal de hopfield</param> /// <returns>Patron grafico</returns> private Pattern neuronsToPattern(List<Neuron> neurons) { var pattern = new Pattern((double)neurons.Count); for (int i = 0; i < neurons.Count; i++) pattern[i] = neurons[i].State == NeuronStates.AgainstField ? 1 : 0; return pattern; }