Beispiel #1
0
        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;
        }
Beispiel #2
0
        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;
        }
Beispiel #3
0
        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);
        }