private static ImageShapeContext createISC(List<Point> edge, int samplecount) { var sample = edge.Sample(samplecount); var norm = Jim.OCR.Algorithms.ShapeContext.Normalize(sample); var scs = new ImageShapeContext(sample); for (int i = 0; i < norm.Length; ++i) { scs.ShapeContests[i] = new Jim.OCR.Algorithms.ShapeContext(norm[i]); } return scs; }
private static ImageShapeContext CreateShapeContext(string path, string fontFamily, int samplecount, char c) { MyTimer timer = new MyTimer(); Font font = new Font(fontFamily, 240); string file = Path.Combine(path, String.Format("{0}-{1}.bmp", fontFamily, c)); string fontpath = Path.Combine(path, fontFamily); Image<Bgr, Byte> img = new Image<Bgr, byte>(400, 400); using (Graphics g = Graphics.FromImage(img.Bitmap)) { g.Clear(Color.Black); g.DrawString(c.ToString(), font, Brushes.White, 0, 0); } timer.Restart(); var canny = img.Convert<Gray, Byte>().Canny(new Gray(100), new Gray(60)); timer.StopAndSay("Canny"); timer.Restart(); List<Point> edge = new List<Point>(); for (int y = 0; y < canny.Height; ++y) { for (int x = 0; x < canny.Width; ++x) { if (canny[y, x].Intensity > 0) { edge.Add(new Point(x, y)); } } } var sample = edge.Sample(samplecount); timer.StopAndSay("Sample"); using (var sw = new StreamWriter(Path.Combine(path, String.Format("!Sample-{0}-{1}.txt", fontFamily, c)))) { foreach (var p in sample) { sw.WriteLine("{0},{1}", p.X, p.Y); } } timer.Restart(); double min, max; var norm = Jim.OCR.Algorithms.ShapeContext.Normalize(sample, out min, out max); timer.StopAndSay("Normalize"); timer.Restart(); var scs = new ImageShapeContext(sample); for (int i = 0; i < norm.Length; ++i) { scs.ShapeContests[i] = new Jim.OCR.Algorithms.ShapeContext(norm[i]); //var his = sc.Histogram.ToImage(); var p = sample[i]; //string hisfile = Path.Combine(fontpath, string.Format("[{0},{1}].bmp", p.X, p.Y)); //his.Save(hisfile); img[p] = new Bgr(0, 0, 255); } timer.StopAndSay("ShapeContext"); //foreach (var p in sample) { // var sc = new ShapeContext(p, sample); // var his = sc.Histogram.ToImage(); // string hisfile = Path.Combine(fontpath, string.Format("[{0},{1}].bmp", p.X, p.Y)); // his.Save(hisfile); // img[p] = new Bgr(0, 0, 255); //} //var contours = img.Convert<Gray, Byte>().FindContours(); //img.Draw(contours, new Bgr(0, 0, 255), new Bgr(0, 255, 0), 2, 1); //dfsContour(img, contours, 0, 2); //foreach (var ii in contours.) { // //Console.WriteLine // img[ii] = new Bgr(0, 0, 255); //} //img.Save(file); return scs; }
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); }