private static void testMNIST() { var timer = new MyTimer(); List<Point>[] Edges = new List<Point>[10]; #region 准备边缘集合 //Font standardFont = new Font("Arial", 20); //for (int i = 0; i < 10; ++i) { // Image<Bgr, Byte> img = new Image<Bgr, byte>(28, 28); // using (Graphics g = Graphics.FromImage(img.Bitmap)) { // g.Clear(Color.Black); // g.DrawString(i.ToString(), standardFont, Brushes.White, 0, 0); // } // Edges[i] = getEdge(img.Convert<Gray, Byte>()); // //img.Save(Path.Combine(@"D:\Play Data\", i + ".bmp")); //} for (int i = 0; i < 10; ++i) { string template = Path.Combine(@"D:\Play Data\template", i + ".bmp"); Image<Gray, Byte> img = new Image<Gray, byte>(template); Edges[i] = getEdge(img); } #endregion List<string> wrong = new List<string>(); int testcount = 100, pos = 0; foreach (var file in Directory.GetFiles(@"D:\Play Data\test", "*.bmp")) { if (pos == testcount) break; string filename = Path.GetFileNameWithoutExtension(file); int ans = int.Parse(filename.Split('-')[1]); timer.Restart(); List<Point> edge = getEdge(new Image<Gray, byte>(file)); ImageShapeContext[] isc1 = new ImageShapeContext[10]; ImageShapeContext[] isc2 = new ImageShapeContext[10]; KM[] kms = new KM[10]; double[] results = new double[10]; int scale = 8; for (int d = 0; d < 10; ++d) { int samplecount = Math.Min(edge.Count, Edges[d].Count); var sc = createISC(edge, samplecount); var sci = createISC(Edges[d], samplecount); var scm = new ShapeContextMatching(sc.ShapeContests, sci.ShapeContests); scm.BuildCostGraph(); var km = scm.Match(); isc1[d] = sc; isc2[d] = sci; kms[d] = km; results[d] = (double)km.MatchResult / samplecount; } var sort = results.Select((c, i) => new { Cost = c, Digit = i }).OrderBy(v => v.Cost).ToArray(); if (sort[0].Digit == ans) { var fc = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Green; string s = String.Format("File:{0}-{1}ms-Right!\t", filename, timer.Stop()); for (int i = 0; i < 4; ++i) { s += String.Format("{0}/{1:F4}, ", sort[i].Digit, sort[i].Cost); } Debug(s); Console.ForegroundColor = fc; } else { var fc = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Red; wrong.Add(filename); string s = String.Format("File:{0}-{1}ms-Wrong!", filename, timer.Stop()); for (int i = 0; i < 5; ++i) { s += String.Format("{0}/{1:F2}, ", sort[i].Digit, sort[i].Cost); } Debug(s); Console.ForegroundColor = fc; string dir = Path.Combine(@"D:\Play Data\output", filename); if (Directory.Exists(dir)) Directory.Delete(dir, true); Directory.CreateDirectory(dir); for (int d = 0; d < 10; ++d) { var sc = isc1[d]; var sci = isc2[d]; var km = kms[d]; int ax = (int)sc.Points.Average(p => p.X), ay = (int)sc.Points.Average(p => p.Y), bx = (int)sci.Points.Average(p => p.X), by = (int)sci.Points.Average(p => p.Y); int dx = bx - ax, dy = by - ay; Image<Bgr, Byte> img = new Image<Bgr, byte>(28 * scale, 28 * scale); Font fs = new Font("Arial", 18); using (Graphics g = Graphics.FromImage(img.Bitmap)) { g.Clear(Color.Black); for (int j = 0; j < sci.Points.Count; ++j) { int i = km.MatchPair[j + sc.Points.Count]; Point pb = sci.Points[j], pa = sc.Points[i]; pb.X -= dx; pb.Y -= dy; int r = 2; g.DrawEllipse(Pens.Red, pa.X * scale - r, pa.Y * scale - r, r * 2 + 1, r * 2 + 1); g.DrawEllipse(Pens.Green, pb.X * scale - r, pb.Y * scale - r, r * 2 + 1, r * 2 + 1); g.DrawLine(Pens.Gray, new Point(pa.X * scale, pa.Y * scale), new Point(pb.X * scale, pb.Y * scale)); } g.DrawString(results[d].ToString(), fs, Brushes.White, new PointF(0, 0)); } img.Save(Path.Combine(dir, d + ".bmp")); } } ++pos; } Debug("Wrong:{0}", wrong.Count); Debug("Wrong rate:{0:F2}%", 100.0 * wrong.Count / testcount); }
private static void MatchShapeContext(string path, string fa, string fb, char c) { MyTimer timer = new MyTimer(); Console.WriteLine("Doing...{0}", c); var sca = CreateShapeContext(path, fa, 100, c); var scb = CreateShapeContext(path, fb, 100, c); var match = new ShapeContextMatching(sca.ShapeContests, scb.ShapeContests); timer.Restart(); match.BuildCostGraph(); timer.StopAndSay("Build Graph"); timer.Restart(); var km = match.Match(); timer.StopAndSay("Match"); Console.WriteLine("Match Result:{0}", km.MatchResult); int ax = (int)sca.Points.Average(p => p.X), ay = (int)sca.Points.Average(p => p.Y), bx = (int)scb.Points.Average(p => p.X), by = (int)scb.Points.Average(p => p.Y); int dx = bx - ax, dy = by - ay; int scale = 4; Image<Bgr, Byte> img = new Image<Bgr, byte>(400 * scale, 400 * scale); string scdir = Path.Combine(path, c.ToString()); if (Directory.Exists(scdir)) Directory.Delete(scdir, true); Directory.CreateDirectory(scdir); Font fs = new Font("Arial", 12); using (Graphics g = Graphics.FromImage(img.Bitmap)) { g.Clear(Color.Black); Font font1 = new Font(fa, 240 * scale); Font font2 = new Font(fb, 240 * scale); g.DrawString(c.ToString(), font1, new SolidBrush(Color.FromArgb(30, 255, 0, 0)), new Point(0, 0)); g.DrawString(c.ToString(), font2, new SolidBrush(Color.FromArgb(30, 0, 255, 0)), new Point(-dx * scale, -dy * scale)); for (int j = 0; j < scb.Points.Count; ++j) { int i = km.MatchPair[j + sca.Points.Count]; Point pb = scb.Points[j], pa = sca.Points[i]; pb.X -= dx; pb.Y -= dy; int r = 3; g.DrawEllipse(Pens.Red, pa.X * scale - r, pa.Y * scale - r, r * 2 + 1, r * 2 + 1); g.DrawEllipse(Pens.Green, pb.X * scale - r, pb.Y * scale - r, r * 2 + 1, r * 2 + 1); g.DrawLine(Pens.Gray, new Point(pa.X * scale, pa.Y * scale), new Point(pb.X * scale, pb.Y * scale)); Point ps = new Point(pa.X * scale, pa.Y * scale); g.DrawString(i.ToString(), fs, Brushes.White, ps); string hisa = Path.Combine(scdir, String.Format("{0}-{1}.bmp", i, fa)); string hisb = Path.Combine(scdir, String.Format("{0}-{1}.bmp", i, fb)); sca.ShapeContests[i].Histogram.ToImage().Save(hisa); scb.ShapeContests[j].Histogram.ToImage().Save(hisb); } } img.Save(Path.Combine(path, String.Format("{0}-{1}-{2}.bmp", fa, fb, c))); }