public double Distance(FrameOfPixels a, FrameOfPixels b) { double distance = 0; for (int i = 0; i < a.pixels.Count(); ++i) { distance += (a.pixels[i].R - b.pixels[i].R) * (a.pixels[i].R - b.pixels[i].R); distance += (a.pixels[i].G - b.pixels[i].G) * (a.pixels[i].G - b.pixels[i].G); distance += (a.pixels[i].B - b.pixels[i].B) * (a.pixels[i].B - b.pixels[i].B); } return(Math.Sqrt(distance)); }
public FrameOfPixels Compare(FrameOfPixels data) { Random rnd = new Random(); double distance = Distance(neurons[0][0].weights, data); double tempDistance = 0; Neuron BMU = new Neuron(sizeOfFrame, 0, rnd); BMU = neurons[0][0]; for (int i = 0; i < gridWidth; ++i) //znajdowanie najbliższego neuronu { for (int j = 0; j < gridHeight; ++j) { tempDistance = Distance(neurons[i][j].weights, data); if (tempDistance < distance) { distance = tempDistance; BMU = neurons[i][j]; } } } return(BMU.weights); }
public double Train(FrameOfPixels data, int iteration_fin, int iteration_curr) { range_curr = range_init * Math.Pow((range_fin / range_init), (iteration_curr / iteration_fin)); learningRate_curr = learningRate_init * Math.Pow((learningRate_fin / learningRate_init), (iteration_curr / iteration_fin)); Random rnd = new Random(); double distance = Distance(neurons[0][0].weights, data); double tempDistance = 0; Neuron BMU = new Neuron(sizeOfFrame, 0, rnd); BMU = neurons[0][0]; int x = 0, y = 0; for (int i = 0; i < gridWidth; ++i) //znajdowanie najbliższego neuronu { for (int j = 0; j < gridHeight; ++j) { tempDistance = Distance(neurons[i][j].weights, data); if (tempDistance < distance) { distance = tempDistance; BMU = neurons[i][j]; x = i; y = j; } } } double dist = 0; for (int i = 0; i < gridWidth; ++i) //znajdowanie najbliższego neuronu { for (int j = 0; j < gridHeight; ++j) { dist = Math.Abs(x - i) + Math.Abs(y - j); for (int z = 0; z < neurons[i][j].weights.pixels.Count(); ++z) { neurons[i][j].weights.pixels[z].R += (int)(Math.Exp((-1) * (dist * dist) / (2 * range_curr * range_curr)) * learningRate_curr * (data.pixels[z].R - neurons[i][j].weights.pixels[z].R)); neurons[i][j].weights.pixels[z].G += (int)(Math.Exp((-1) * (dist * dist) / (2 * range_curr * range_curr)) * learningRate_curr * (data.pixels[z].G - neurons[i][j].weights.pixels[z].G)); neurons[i][j].weights.pixels[z].B += (int)(Math.Exp((-1) * (dist * dist) / (2 * range_curr * range_curr)) * learningRate_curr * (data.pixels[z].B - neurons[i][j].weights.pixels[z].B)); //im so sorry for that if (neurons[i][j].weights.pixels[z].R > 255) { neurons[i][j].weights.pixels[z].R = 255; } if (neurons[i][j].weights.pixels[z].G > 255) { neurons[i][j].weights.pixels[z].G = 255; } if (neurons[i][j].weights.pixels[z].B > 255) { neurons[i][j].weights.pixels[z].B = 255; } if (neurons[i][j].weights.pixels[z].R < 0) { neurons[i][j].weights.pixels[z].R = 0; } if (neurons[i][j].weights.pixels[z].G < 0) { neurons[i][j].weights.pixels[z].G = 0; } if (neurons[i][j].weights.pixels[z].B < 0) { neurons[i][j].weights.pixels[z].B = 0; } if (mode == 0) { int q = (neurons[i][j].weights.pixels[z].R + neurons[i][j].weights.pixels[z].G + neurons[i][j].weights.pixels[z].B) / 3; neurons[i][j].weights.pixels[z].R = q; neurons[i][j].weights.pixels[z].G = q; neurons[i][j].weights.pixels[z].B = q; } } } } distance = Distance(BMU.weights, data); return(distance * distance); }
public Neuron(int SIZE_OF_FRAME, int MODE, Random rnd) //mode = 0 -> gray, 1 -> color { weights = new FrameOfPixels(SIZE_OF_FRAME, MODE, rnd); }
public void TrainAndDraw(Bitmap image, Bitmap resultImage) { //source image BitmapData imageData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); byte[] imageBytes = new byte[Math.Abs(imageData.Stride) * image.Height]; IntPtr scan0 = imageData.Scan0; Marshal.Copy(scan0, imageBytes, 0, imageBytes.Length); //result image BitmapData resultImageData = resultImage.LockBits(new Rectangle(0, 0, resultImage.Width, resultImage.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); byte[] resultImageBytes = new byte[Math.Abs(resultImageData.Stride) * resultImage.Height]; scan0 = resultImageData.Scan0; Marshal.Copy(scan0, resultImageBytes, 0, resultImageBytes.Length); FrameOfPixels frame = new FrameOfPixels(sizeOfFrame); Random rnd = new Random(); NeuralNetwork nn = new NeuralNetwork(nnWidth, nnHeight, sizeOfFrame, mode, Convert.ToDouble(RANGE_init.Text), Convert.ToDouble(RANGE_fin.Text), Convert.ToDouble(LR_init.Text), Convert.ToDouble(LR_fin.Text)); epochs = Convert.ToInt32(epochs_text.Text); //nauka int randX = image.Width / sizeOfFrame; int randY = image.Height / sizeOfFrame; int spawnX = rnd.Next(0, randX); int spawnY = rnd.Next(0, randY); double quantization_error = 0; int strideWidthDivided = imageData.Stride / 3; int strideWidth = imageData.Stride; int resultStrideWidth = resultImageData.Stride; int heightDivided = image.Height / sizeOfFrame; int widthDivided = image.Width / sizeOfFrame; for (int i = 0; i < epochs; ++i) { /*spawnX = rnd.Next(0, randX); * spawnY = rnd.Next(0, randY); * for (int p = spawnY; p < spawnY + sizeOfFrame; ++p) * { * for (int z = spawnX; z < spawnX + sizeOfFrame; ++z) * { * int a = p * strideWidth + z * 3; * * frame.pixels.Add(new Pixel(imageBytes[a + 2], imageBytes[a + 1], imageBytes[a])); * } * }*/ //po kolei /*for (int o = 0; o < image.Height - (image.Height % sizeOfFrame); o += sizeOfFrame) * { * for (int j = 0; j < image.Width - (image.Width % sizeOfFrame); j += sizeOfFrame) * { * for (int p = o; p < o + sizeOfFrame; ++p) * { * for (int z = j; z < j + sizeOfFrame; ++z) * { * int a = p * strideWidth + z * 3; * * frame.pixels.Add(new Pixel(imageBytes[a + 2], imageBytes[a + 1], imageBytes[a])); * } * } * quantization_error += nn.Train(frame, epochs, i); * frame.pixels.Clear(); * } * }*/ foreach (int o in Enumerable.Range(0, heightDivided).OrderBy(x => rnd.Next())) { foreach (int j in Enumerable.Range(0, widthDivided).OrderBy(x => rnd.Next())) { for (int p = o * sizeOfFrame; p < o * sizeOfFrame + sizeOfFrame; ++p) { for (int z = j * sizeOfFrame; z < j * sizeOfFrame + sizeOfFrame; ++z) { int a = p * strideWidth + z * 3; frame.pixels.Add(new Pixel(imageBytes[a + 2], imageBytes[a + 1], imageBytes[a])); } } quantization_error += nn.Train(frame, epochs, i); frame.pixels.Clear(); } } } Console.WriteLine("Quantization error: " + quantization_error / epochs); //wypełnianie for (int i = 0; i < image.Height - (image.Height % sizeOfFrame); i += sizeOfFrame) { for (int j = 0; j < image.Width - (image.Width % sizeOfFrame); j += sizeOfFrame) { for (int p = i; p < i + sizeOfFrame; ++p) { for (int z = j; z < j + sizeOfFrame; ++z) { int a = p * strideWidth + z * 3; if (mode == 0) { int q = (imageBytes[a + 2] + imageBytes[a + 1] + imageBytes[a]) / 3; imageBytes[a + 2] = (byte)q; imageBytes[a + 1] = (byte)q; imageBytes[a] = (byte)q; } frame.pixels.Add(new Pixel(imageBytes[a + 2], imageBytes[a + 1], imageBytes[a])); } } FrameOfPixels BMU = new FrameOfPixels(sizeOfFrame); BMU = nn.Compare(frame); int index = 0; frame.pixels.Clear(); //wypełnienie for (int p = i; p < i + sizeOfFrame; ++p) { for (int z = j; z < j + sizeOfFrame; ++z) { int a = p * resultStrideWidth + z * 3; resultImageBytes[a] = (byte)BMU.pixels[index].B; resultImageBytes[a + 1] = (byte)BMU.pixels[index].G; resultImageBytes[a + 2] = (byte)BMU.pixels[index].R; ++index; } } } } /* Marshal.Copy(imageBytes, 0, scan0, imageBytes.Length); * image.UnlockBits(imageData);*/ Marshal.Copy(resultImageBytes, 0, scan0, resultImageBytes.Length); resultImage.UnlockBits(resultImageData); }