public int Teach(System.Drawing.Bitmap data, ref ProgressState progress) { System.Drawing.Color[] c = new System.Drawing.Color[data.Width * data.Height]; progress.NameOfStage = "Bitmap to Color List"; progress.MaxEpochStage = c.Length; for (int i = 0; i < data.Width; i++) { for (int j = 0; j < data.Height; j++) { c[i * data.Height + j] = data.GetPixel(i, j); progress.EpochStage = i * data.Width + j; } } return(Teach(c, ref progress)); }
public override int Teach(System.Drawing.Color[] data, ref ProgressState progress) { if (Clusters.Length < 1) { return(-1); } progress.Utilizing = this.ToString(); //рабочее представление кластера BitmapCluster[] _clusters = new BitmapCluster[Clusters.Length]; //первичная инициализация рабочего представления кластера на основе начальных точек for (int i = 0; i < _clusters.Length; i++) { _clusters[i] = new BitmapCluster(); _clusters[i].Value.R = Clusters[i].R; _clusters[i].Value.G = Clusters[i].G; _clusters[i].Value.B = Clusters[i].B; } float minRgbError, oldRgbError = 0; int epoch = 0; while (true) { //Инициализация рабочего представления кластера для текущей итерации for (int i = 0; i < _clusters.Length; i++) { byte R = (byte)_clusters[i].Value.R; byte G = (byte)_clusters[i].Value.G; byte B = (byte)_clusters[i].Value.B; System.Drawing.Color C = System.Drawing.Color.FromArgb(255, R, G, B); Clusters[i] = C; _clusters[i].Count = 0; _clusters[i].Value.R = 0; _clusters[i].Value.G = 0; _clusters[i].Value.B = 0; } for (int i = 0; i < data.Length; i++) { // получаем RGB-компоненты пикселя byte R = data[i].R; byte G = data[i].G; byte B = data[i].B; System.Drawing.Color C = System.Drawing.Color.FromArgb(255, R, G, B); minRgbError = 255 * 255 * 255; int clusterIndex = -1; for (int k = 0; k < _clusters.Length; k++) { float euclid = ErrorRule(C, Clusters[k]); if (euclid < minRgbError) { minRgbError = euclid; clusterIndex = k; } } // устанавливаем индекс кластера _clusters[clusterIndex].Count++; _clusters[clusterIndex].Value.R += R; _clusters[clusterIndex].Value.G += G; _clusters[clusterIndex].Value.B += B; } minRgbError = 0; for (int k = 0; k < _clusters.Length; k++) { // new color if (_clusters[k].Count > 1) { _clusters[k].Center(); } byte R = (byte)_clusters[k].Value.R; byte G = (byte)_clusters[k].Value.G; byte B = (byte)_clusters[k].Value.B; System.Drawing.Color C = System.Drawing.Color.FromArgb(255, R, G, B); float ecli = ErrorRule(C, Clusters[k]); if (ecli > minRgbError) { minRgbError = ecli; } } epoch++; if (Math.Abs(minRgbError - oldRgbError) < 1 || minRgbError < 50 || epoch == 50) { break; } oldRgbError = minRgbError; } // теперь загоним массив в вектор и отсортируем List <KeyValuePair <int, uint> > colors = new List <KeyValuePair <int, uint> >(); int colors_count = 0; for (int i = 0; i < Clusters.Length; i++) { KeyValuePair <int, uint> color = new KeyValuePair <int, uint>(i, _clusters[i].Count); colors.Add(color); if (_clusters[i].Count > 0) { colors_count++; } } colors.Sort(CompareClusters); for (int i = 0; i < Clusters.Length; i++) { byte R = (byte)_clusters[colors[i].Key].Value.R; byte G = (byte)_clusters[colors[i].Key].Value.G; byte B = (byte)_clusters[colors[i].Key].Value.B; Clusters[i] = System.Drawing.Color.FromArgb(255, R, G, B); } return(epoch); }
/// <summary> /// Заупск обучения кластеризации, резуьтат которой будет обучение кластеров для разделения /// входных данных на группы /// </summary> /// <param name="data">Массив входных данных </param> /// <param name="progress">Состояние прогресса алгоритма</param> /// <returns>Количество итераций, за которое алгоритм сошелся</returns> public abstract int Teach(T[] data, ref ProgressState progress);