private Image <Bgr, Byte> kmeans() { int trainSampleCount = 1500; int sigma = 60; Matrix <float> trainData = new Matrix <float>(trainSampleCount, 2); Matrix <float> trainData1 = trainData.GetRows(0, trainSampleCount / 3, 1); trainData1.GetCols(0, 1).SetRandNormal(new MCvScalar(100), new MCvScalar(sigma)); trainData1.GetCols(1, 2).SetRandNormal(new MCvScalar(300), new MCvScalar(sigma)); Matrix <float> trainData2 = trainData.GetRows(trainSampleCount / 3, 2 * trainSampleCount / 3, 1); trainData2.SetRandNormal(new MCvScalar(400), new MCvScalar(sigma)); Matrix <float> trainData3 = trainData.GetRows(2 * trainSampleCount / 3, trainSampleCount, 1); trainData3.GetCols(0, 1).SetRandNormal(new MCvScalar(300), new MCvScalar(sigma)); trainData3.GetCols(1, 2).SetRandNormal(new MCvScalar(100), new MCvScalar(sigma)); PointF[] points = new PointF[trainSampleCount]; for (int i = 0; i < points.Length; ++i) { points[i] = new PointF(trainData[i, 0], trainData[i, 1]); } var km = new KMeans <PointF>(points, 3, (a, b) => ((a.X - b.X) * (a.X - b.X) + (a.Y - b.Y) * (a.Y - b.Y)), list => new PointF(list.Average(p => p.X), list.Average(p => p.Y)) ); int it = 0; MyTimer timer = new MyTimer(); timer.Restart(); //var cluster = km.Cluster(); var cluster = km.AnnealCluster( (a, b) => new PointF(a.X + b.X, a.Y + b.Y), (a, b) => new PointF(a.X - b.X, a.Y - b.Y), (p, v) => new PointF((float)(p.X / v), (float)(p.Y / v)), out it); var time = timer.Stop(); this.Text = String.Format("n={0}, k={1}, time={2}ms, iter={3}.", trainSampleCount, 3, time, it); Image <Bgr, Byte> img = new Image <Bgr, byte>(500, 500); for (int y = 0; y < 500; ++y) { for (int x = 0; x < 500; ++x) { double d0 = (x - cluster[0].Center.X) * (x - cluster[0].Center.X) + (y - cluster[0].Center.Y) * (y - cluster[0].Center.Y); double d1 = (x - cluster[1].Center.X) * (x - cluster[1].Center.X) + (y - cluster[1].Center.Y) * (y - cluster[1].Center.Y); double d2 = (x - cluster[2].Center.X) * (x - cluster[2].Center.X) + (y - cluster[2].Center.Y) * (y - cluster[2].Center.Y); Bgr color = new Bgr(0, 0, 0); if (d0 < d1 && d0 < d2) { color = new Bgr(20, 0, 0); } if (d1 < d0 && d1 < d2) { color = new Bgr(0, 20, 0); } if (d2 < d0 && d2 < d1) { color = new Bgr(0, 0, 20); } img[y, x] = color; } } Bgr[] colors = new[] { new Bgr(128, 0, 0), new Bgr(0, 128, 0), new Bgr(0, 0, 128) }; Bgr[] centers = new[] { new Bgr(255, 0, 0), new Bgr(0, 255, 0), new Bgr(0, 0, 255) }; for (int i = 0; i < 3; ++i) { foreach (var p in cluster[i]) { img.Draw(new CircleF(p, 2), colors[i], 1); } img.Draw(new CircleF(cluster[i].Center, 5), centers[i], 3); } img.Draw(new CircleF(new PointF(100, 300), sigma), new Bgr(128, 128, 128), 2); img.Draw(new CircleF(new PointF(100, 300), 3), new Bgr(128, 128, 128), 2); img.Draw(new CircleF(new PointF(300, 100), sigma), new Bgr(128, 128, 128), 2); img.Draw(new CircleF(new PointF(300, 100), 3), new Bgr(128, 128, 128), 2); img.Draw(new CircleF(new PointF(400, 400), sigma), new Bgr(128, 128, 128), 2); img.Draw(new CircleF(new PointF(400, 400), 3), new Bgr(128, 128, 128), 2); return(img); }
private Image<Bgr, Byte> kmeans() { int trainSampleCount = 1500; int sigma = 60; Matrix<float> trainData = new Matrix<float>(trainSampleCount, 2); Matrix<float> trainData1 = trainData.GetRows(0, trainSampleCount / 3, 1); trainData1.GetCols(0, 1).SetRandNormal(new MCvScalar(100), new MCvScalar(sigma)); trainData1.GetCols(1, 2).SetRandNormal(new MCvScalar(300), new MCvScalar(sigma)); Matrix<float> trainData2 = trainData.GetRows(trainSampleCount / 3, 2 * trainSampleCount / 3, 1); trainData2.SetRandNormal(new MCvScalar(400), new MCvScalar(sigma)); Matrix<float> trainData3 = trainData.GetRows(2 * trainSampleCount / 3, trainSampleCount, 1); trainData3.GetCols(0, 1).SetRandNormal(new MCvScalar(300), new MCvScalar(sigma)); trainData3.GetCols(1, 2).SetRandNormal(new MCvScalar(100), new MCvScalar(sigma)); PointF[] points = new PointF[trainSampleCount]; for (int i = 0; i < points.Length; ++i) { points[i] = new PointF(trainData[i, 0], trainData[i, 1]); } var km = new KMeans<PointF>(points, 3, (a, b) => ((a.X - b.X) * (a.X - b.X) + (a.Y - b.Y) * (a.Y - b.Y)), list => new PointF(list.Average(p => p.X), list.Average(p => p.Y)) ); int it = 0; MyTimer timer = new MyTimer(); timer.Restart(); //var cluster = km.Cluster(); var cluster = km.AnnealCluster( (a, b) => new PointF(a.X + b.X, a.Y + b.Y), (a, b) => new PointF(a.X - b.X, a.Y - b.Y), (p, v) => new PointF((float)(p.X / v), (float)(p.Y / v)), out it); var time = timer.Stop(); this.Text = String.Format("n={0}, k={1}, time={2}ms, iter={3}.", trainSampleCount, 3, time, it); Image<Bgr, Byte> img = new Image<Bgr, byte>(500, 500); for (int y = 0; y < 500; ++y) { for (int x = 0; x < 500; ++x) { double d0 = (x - cluster[0].Center.X) * (x - cluster[0].Center.X) + (y - cluster[0].Center.Y) * (y - cluster[0].Center.Y); double d1 = (x - cluster[1].Center.X) * (x - cluster[1].Center.X) + (y - cluster[1].Center.Y) * (y - cluster[1].Center.Y); double d2 = (x - cluster[2].Center.X) * (x - cluster[2].Center.X) + (y - cluster[2].Center.Y) * (y - cluster[2].Center.Y); Bgr color = new Bgr(0, 0, 0); if (d0 < d1 && d0 < d2) { color = new Bgr(20, 0, 0); } if (d1 < d0 && d1 < d2) { color = new Bgr(0, 20, 0); } if (d2 < d0 && d2 < d1) { color = new Bgr(0, 0, 20); } img[y, x] = color; } } Bgr[] colors = new[] { new Bgr(128, 0, 0), new Bgr(0, 128, 0), new Bgr(0, 0, 128) }; Bgr[] centers = new[] { new Bgr(255, 0, 0), new Bgr(0, 255, 0), new Bgr(0, 0, 255) }; for (int i = 0; i < 3; ++i) { foreach (var p in cluster[i]) { img.Draw(new CircleF(p, 2), colors[i], 1); } img.Draw(new CircleF(cluster[i].Center, 5), centers[i], 3); } img.Draw(new CircleF(new PointF(100, 300), sigma), new Bgr(128, 128, 128), 2); img.Draw(new CircleF(new PointF(100, 300), 3), new Bgr(128, 128, 128), 2); img.Draw(new CircleF(new PointF(300, 100), sigma), new Bgr(128, 128, 128), 2); img.Draw(new CircleF(new PointF(300, 100), 3), new Bgr(128, 128, 128), 2); img.Draw(new CircleF(new PointF(400, 400), sigma), new Bgr(128, 128, 128), 2); img.Draw(new CircleF(new PointF(400, 400), 3), new Bgr(128, 128, 128), 2); return img; }