Esempio n. 1
0
 public override void Recycle()
 {
     base.Recycle();
     t     = 0;
     speed = 4;
     recycleTimer.Restart();
 }
Esempio n. 2
0
    public void Tick()
    {
        if (curCount == count)
        {
            Fire();
            count--;
        }
        timer.Tick();
        if (timer.state == MyTimer.STATE.finished && count != 0)
        {
            Fire();
            if (count != -1)
            {
                count--;
            }

            timer.Restart();
        }
    }
Esempio n. 3
0
        private static void fastPruningWithRSC()
        {
            int s = 100, r = 5;
            MyTimer timer = new MyTimer();

            string[] templatefiles = Directory.GetFiles(@"D:\Play Data\train_data\sc\", "*.sc")
                .Take(1000).ToArray();
            #region 打开模板
            string templatepath = @"D:\Play Data\template\";
            int templatecount = templatefiles.Length;
            Debug("打开{0}个模板--------------------------------------------", templatecount);
            double[][,] templates = new double[templatecount][,];
            int[] templatenums = new int[templatecount];
            timer.Restart();
            for (int i = 0; i < templatefiles.Length; ++i) {
                string file = templatefiles[i];
                string filename = Path.GetFileNameWithoutExtension(file);
                templatenums[i] = int.Parse(filename.Split('-')[1]);
                templates[i] = new double[s, 60];
                unsafe {
                    #region 指针也快不了多少
                    //byte[] data = File.ReadAllBytes(file);
                    //fixed (byte* ptr = data) {
                    //    //using (var fs = new FileStream(file, FileMode.Open)) {
                    //    //    using (var br = new BinaryReader(fs)) {
                    //    int offset = 0;
                    //    for (int j = 0; j < s; ++j) {
                    //        for (int k = 0; k < 60; ++k) {
                    //            //templates[i][j, k] = br.ReadDouble();
                    //            fixed (double* t = &templates[i][j, k]) {
                    //                for (int p = 0; p < sizeof(double); ++p)
                    //                    *((byte*)t + p) = *(ptr + offset++);
                    //            }
                    //        }
                    //    }
                    //}
                    #endregion
                    using (var fs = new FileStream(file, FileMode.Open)) {
                        using (var br = new BinaryReader(fs)) {
                            for (int j = 0; j < s; ++j) {
                                for (int k = 0; k < 60; ++k) {
                                    templates[i][j, k] = br.ReadDouble();
                                }
                            }
                        }
                    }
                }
                if (i % 100 == 0)
                    Debug("已完成{0}个", i);
            }
            Debug("模板读取完成,用时{0}ms.", timer.Stop());
            #endregion

            string[] testfiles = Directory.GetFiles(@"D:\Play Data\test\", "*.bmp")
                .Take(100).ToArray();
            #region 测试
            int testcase = testfiles.Length, acc = 0;
            Debug("为{0}个对象寻找候选模板------------------------------------------", testcase);
            foreach (var file in testfiles) {
                timer.Restart();
                string filenameext = Path.GetFileName(file);
                string filename = Path.GetFileNameWithoutExtension(file);
                int thisnum = int.Parse(filename.Split('-')[1]);
                Image<Gray, Byte> img = new Image<Gray, byte>(file);
                var list = getEdge(img.Resize(2.5, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR)).Sample(s);
                var sc100 = Jim.OCR.ShapeContext2D.ShapeContext.ComputeSC(list);
                double[,] scq = new double[r, 60];
                for (int i = 0; i < 5; ++i) {
                    int pos = rand.Next(s);
                    for (int k = 0; k < 60; ++k) {
                        scq[i, k] = sc100[pos, k];
                    }
                }
                var arr = new ValueIndexPair<double>[templatecount];
                for (int i = 0; i < templatecount; ++i) {
                    double[,] sci = templates[i];
                    double[,] costmat = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(scq, sci);
                    double cost = 0;
                    for (int j = 0; j < 5; ++j) {
                        double min = double.MaxValue;
                        for (int u = 0; u < s; ++u) {
                            double val = costmat[j, u];
                            if (val < min) min = val;
                        }
                        cost += min;
                    }
                    arr[i] = new ValueIndexPair<double> { Value = cost, Index = i };
                }
                Array.Sort(arr, (a, b) => a.Value.CompareTo(b.Value));
                int[] matchcount = new int[10];
                double[] matchcost = new double[10];
                int knn = 10;
                foreach (var pair in arr.Take(knn)) {
                    int num = templatenums[pair.Index];
                    matchcount[num]++;
                    matchcost[num] += pair.Value;
                }
                var match = matchcount.Select((val, i) => new { Count = val, Num = i })
                                      .Where(v => v.Count > 0)
                                      .OrderByDescending(v => v.Count).ToArray();
                //var match = matchcost.Select((val, i) => new { Cost = val / matchcount[i], Num = i })
                //                     .Where(v => !double.IsNaN(v.Cost))
                //                     .OrderBy(v => v.Cost).ToArray();

                #region 进行精细匹配,效果一般
                //double[] matchrate = new double[10];
                //foreach (var m in match) {
                //    if (m.Count == 0) break;
                //    string template = Path.Combine(templatepath, m.Num + ".bmp");
                //    Jim.OCR.ShapeContext2D.ShapeContext sc = new Jim.OCR.ShapeContext2D.ShapeContext(file, template);
                //    sc.debug_flag = false;
                //    sc.timer_flag = false;
                //    sc.display_flag = false;
                //    sc.n_iter = 3;
                //    sc.matchScale = 2.5;
                //    sc.maxsamplecount = 100;
                //    matchrate[m.Num] = sc.MatchFile();
                //}
                //var bestmatches = matchrate.Select((val, i) => new { Cost = val, Num = i })
                //                           .Where(m => m.Cost > 0)
                //                           .OrderBy(m => m.Cost).ToArray();
                //int firstmatch = bestmatches[0].Num;
                #endregion

                int firstmatch = match[0].Num;
                var fc = Console.ForegroundColor;
                Console.ForegroundColor = firstmatch == thisnum ? ConsoleColor.Green : ConsoleColor.Red;
                string info = String.Format("{0} {1}ms - {2}\t", filename, timer.Stop(), (firstmatch == thisnum ? "Right" : "Wrong"));
                //foreach (var m in bestmatches.Take(4)) {
                foreach (var m in match) {
                    info += String.Format("{0}/{1}\t", m.Num, m.Count);
                    //info += String.Format("{0}/{1:F3}\t", m.Num, m.Cost);
                    //info += String.Format("{0}/{1:F3}\t", m.Num, m.Cost);
                }
                Debug(info);
                Console.ForegroundColor = fc;

                if (firstmatch == thisnum) {
                    ++acc;
                }
            }
            Debug("测试用例:{0}。正确率{1}。", testcase, acc);
            #endregion
        }
Esempio n. 4
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;
        }
Esempio n. 5
0
 private static void computeTemplateSC(int start, int count)
 {
     int s = 100;
     string[] templatefiles = Directory.GetFiles(@"D:\Play Data\my_template\", "*.jpg")
         .Skip(start).Take(count).ToArray();
     int templatecount = templatefiles.Length;
     Debug("解析{0}个模板--------------------------------------------", templatecount);
     MyTimer timer = new MyTimer();
     timer.Restart();
     for (int i = 0; i < templatecount; ++i) {
         string file = templatefiles[i];
         string filenameext = Path.GetFileName(file);
         string filename = Path.GetFileNameWithoutExtension(file);
         Image<Gray, Byte> img = new Image<Gray, byte>(file);
         var list = getEdge(img.Resize(2.5, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR)).Sample(s);
         if (i % 100 == 0)
             Debug("已完成{0}个", i);
         var sc = Jim.OCR.ShapeContext2D.ShapeContext.ComputeSC(list);
         using (var fs = new FileStream(Path.Combine(@"D:\Play Data\my_template_data\sc\", filename + ".sc"), FileMode.Create))
         {
             using (var bw = new BinaryWriter(fs)) {
                 for (int j = 0; j < s; ++j) {
                     for (int k = 0; k < 60; ++k) {
                         bw.Write(sc[j, k]);
                     }
                 }
             }
         }
     }
     Debug("模板计算完成,用时{0}ms.", timer.Stop());
 }
Esempio n. 6
0
        private static void clusterSC()
        {
            int s = 100, K = 100;
            string[] templatefiles = Directory.GetFiles(@"D:\Play Data\my_template_data\sc\", "*.sc")
                .Take(180).ToArray();
            int templatecount = templatefiles.Length;
            #region 读取模板
            Debug("打开{0}个模板--------------------------------------------", templatecount);
            double[][] templates = new double[templatecount * s][];
            MyTimer timer = new MyTimer();
            timer.Restart();
            for (int i = 0; i < templatefiles.Length; ++i) {
                string file = templatefiles[i];
                string filename = Path.GetFileNameWithoutExtension(file);
                using (var fs = new FileStream(file, FileMode.Open)) {
                    using (var br = new BinaryReader(fs)) {
                        for (int j = 0; j < s; ++j) {
                            templates[i * s + j] = new double[60];
                            for (int k = 0; k < 60; ++k) {
                                templates[i * s + j][k] = br.ReadDouble();
                            }
                        }
                    }
                }
                if (i % 100 == 0)
                    Debug("已完成{0}个", i);
            }
            Debug("模板读取完成,用时{0}ms.", timer.Stop());
            #endregion

            #region 聚类
            timer.Restart();
            KMeans<double[]> kmeans = new KMeans<double[]>(templates, K,
                Jim.OCR.ShapeContext2D.ShapeContext.HistCost,
                scs => {
                    double[] scnew = new double[60];
                    for (int k = 0; k < 60; ++k) {
                        scnew[k] = scs.Average(sc => sc[k]);
                    }
                    return scnew;
                }
            );
            kmeans.MaxIterate = 100;
            var cluster = kmeans.Cluster();
            Debug("聚类完成,用时{0}ms.", timer.Stop());
            #endregion

            using (var fs = new FileStream(Path.Combine(@"D:\Play Data\my_template_data\sm-" + K, templatecount + ".sm"), FileMode.Create))
            {
                using (var bw = new BinaryWriter(fs)) {
                    for (int i = 0; i < K; ++i) {
                        for (int k = 0; k < 60; ++k) {
                            bw.Write(cluster[i].Center[k]);
                        }
                    }
                }
            }
        }
Esempio n. 7
0
        private static void testMNIST2()
        {
            List<string> wrong = new List<string>();
            int testcount = 100, pos = 0;

            MyTimer timer = new MyTimer();

            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();
                double[] results = new double[10];

                int scale = 8;
                for (int d = 0; d < 10; ++d) {
                    string template = Path.Combine(@"D:\Play Data\template", d + ".bmp");
                    var sc = new Jim.OCR.ShapeContext2D.ShapeContext(file, template);
                    sc.n_iter = 1;
                    //sc.showScale = 6;
                    sc.matchScale = 2.5;
                    sc.maxsamplecount = 100;
                    sc.display_flag = false;
                    sc.debug_flag = false;
                    sc.timer_flag = false;
                    double matchcost = sc.MatchFile();
                    results[d] = matchcost;// / sc.nsamp;
                }
                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;
                    //Debug("File:{0}-{1}ms-Opps!", filename, Timer.Stop());
                    wrong.Add(filename);
                    string s = String.Format("File:{0}-{1}ms-Wrong!\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;

                    #region 画对比图
                    //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"));
                    //}
                    #endregion
                }
                ++pos;
            }

            Debug("Wrong:{0}", wrong.Count);
            Debug("Wrong rate:{0:F2}%", 100.0 * wrong.Count / testcount);
        }
Esempio n. 8
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);
        }
Esempio n. 9
0
        private void openSC(string dir)
        {
            new Thread(new ThreadStart(() => {
                timer.Restart();
                const int shapeme_count = 100;
                shapemes = new double[shapeme_count][];
                showStatus("加载Shapeme");
                #region Shapeme
                using (var fs = new FileStream(Path.Combine(dir, "data.sm"), FileMode.Open)) {
                    using (var br = new BinaryReader(fs)) {
                        for (int i = 0; i < shapeme_count; ++i)
                        {
                            shapemes[i] = new double[60];
                            for (int k = 0; k < 60; ++k)
                            {
                                shapemes[i][k] = br.ReadDouble();
                            }
                            showProgress((i + 1.0) / shapeme_count);
                        }
                    }
                }
                #endregion

                #region SCQ
                showStatus("加载量化形状上下文");
                var template_files  = Directory.GetFiles(Path.Combine(dir, "scq"), "*.scq").ToArray();
                int template_count  = template_files.Length;
                template_histograms = new int[template_count][];
                template_chars      = new string[template_count];
                for (int f = 0; f < template_count; ++f)
                {
                    string file            = template_files[f];
                    string filename        = Path.GetFileNameWithoutExtension(file);
                    template_chars[f]      = filename.Split('-')[1];
                    template_histograms[f] = new int[shapeme_count];
                    using (var fs = new FileStream(file, FileMode.Open)) {
                        using (var br = new BinaryReader(fs)) {
                            for (int i = 0; i < shapeme_count; ++i)
                            {
                                template_histograms[f][i] = br.ReadInt32();
                            }
                        }
                    }
                    showProgress((f + 1.0) / template_count);
                }
                #endregion

                #region SC
                showStatus("加载形状上下文");
                var sc_files = Directory.GetFiles(Path.Combine(dir, "sc"), "*.sc").ToArray();
                template_sc  = new double[template_count][, ];
                for (int f = 0; f < template_count; ++f)
                {
                    string file     = sc_files[f];
                    string filename = Path.GetFileNameWithoutExtension(file);
                    template_sc[f]  = new double[100, 60];
                    using (var fs = new FileStream(file, FileMode.Open)) {
                        using (var br = new BinaryReader(fs)) {
                            for (int j = 0; j < 100; ++j)
                            {
                                for (int k = 0; k < 60; ++k)
                                {
                                    template_sc[f][j, k] = br.ReadDouble();
                                }
                            }
                        }
                    }
                    showProgress((f + 1.0) / template_count);
                }
                #endregion
                showStatus("加载完成,用时{0}ms。", timer.Stop());
            })).Start();
        }
Esempio n. 10
0
        private static void testCAPTCHA()
        {
            var timer = new MyTimer();
            int s = 100, K = 100, m = 180;

            string[] templatefiles = Directory.GetFiles(@"D:\Play Data\my_template_data\scq-" + K + "-" + m, "*.scq")
                .Take(10000).ToArray();
            #region 打开量化的模板
            int templatecount = templatefiles.Length;
            Debug("打开{0}个量化模板----------------------------------------", templatecount);
            timer.Restart();
            int[][] templatehistograms = new int[templatecount][];
            string[] templatechars = new string[templatecount];
            for (int f = 0; f < templatecount; ++f) {
                string file = templatefiles[f];
                string filename = Path.GetFileNameWithoutExtension(file);
                templatechars[f] = filename.Split('-')[1];
                templatehistograms[f] = new int[K];
                using (var fs = new FileStream(file, FileMode.Open)) {
                    using (var br = new BinaryReader(fs)) {
                        for (int i = 0; i < K; ++i) {
                            templatehistograms[f][i] = br.ReadInt32();
                        }
                    }
                }
            }
            Debug("打开完成,用时{0}ms.", timer.Stop());

            #endregion

            #region 打开Shapeme
            Debug("打开{0}个Shapeme.", K);
            timer.Restart();
            double[][] shapemes = new double[K][];
            using (var fs = new FileStream(Path.Combine(@"D:\Play Data\my_template_data\sm-" + K, m + ".sm"), FileMode.Open)) {
                using (var br = new BinaryReader(fs)) {
                    for (int i = 0; i < K; ++i) {
                        shapemes[i] = new double[60];
                        for (int k = 0; k < 60; ++k) {
                            shapemes[i][k] = br.ReadDouble();
                        }
                    }
                }
            }

            Debug("Shapeme读取完成,用时{0}ms.", timer.Stop());
            #endregion

            #region 识别
            foreach (var challengeFile in Directory.GetFiles(@"D:\Play Data\字符\", "*.jpg")) {
                timer.Restart();
                string filename = Path.GetFileNameWithoutExtension(challengeFile);
                Image<Gray, Byte> img = new Image<Gray, byte>(challengeFile);
                var mmp = img.Convert<Bgr, Byte>();
                Graphics g = Graphics.FromImage(mmp.Bitmap);
                double width_height_ratio = (double)img.Width / img.Height;
                int sq = (int)(s * width_height_ratio * 1.2);
                int randcount = (int)(width_height_ratio * 2);
                //int windowcount = (int)(width_height_ratio * 2),
                //    windowstep = (int)(img.Width / windowcount),
                //    windowwidth = (int)(img.Width * 1.5 / windowcount);
                //int maxrandcount = randcount * 3;
                //Console.WriteLine("宽高比{0:F2},采样{1},随机数{2},随机上限{3}.",
                //    width_height_ratio, sq, randcount, maxrandcount);
                int slice = 16,//(int)(width_height_ratio * width_height_ratio),
                    overlap = 4,
                    windowcount = 7;//slice - (overlap - 1);
                double slice_width = (double)img.Width / slice;
                Console.WriteLine("宽高比{0:F2},切片数{1},切片宽度{2:F2},窗口数{3}.",
                    width_height_ratio, slice, slice_width, windowcount);
                var edge = getEdge(img).Sample(sq);
                foreach (var p in edge) {
                    mmp[p] = new Bgr(0, 0, 127);
                }
                bool[] edge_vi = Utils.InitArray(sq, false);
                #region 计算采样点之间的距离
                ValueIndexPair<double>[][] edgedists = new ValueIndexPair<double>[sq][];
                for (int i = 0; i < sq; ++i) {
                    edgedists[i] = new ValueIndexPair<double>[sq];
                    for (int j = 0; j < sq; ++j) {
                        double xi = edge[i].X, yi = edge[i].Y,
                               xj = edge[j].X, yj = edge[j].Y;
                        double d = Math.Sqrt((xi - xj) * (xi - xj) + (yi - yj) * (yi - yj));
                        edgedists[i][j] = new ValueIndexPair<double> { Value = d, Index = j };
                    }
                    Array.Sort(edgedists[i], (a, b) => a.Value.CompareTo(b.Value));
                }
                #endregion

                var charlist = new List<Tuple<string, int, PointF>>(); // <ch, count, center>
                //for (int rc = 0, rt = 0; rc < randcount && rt < maxrandcount; ++rt) {
                //    #region 随机取一个中心点,并且取离他近的点计算形状上下文
                //int center = rand.Next(sq);
                //if (edge_vi[center]) continue;
                //else rc++;
                //rc++;
                //var nearby = new List<Point>();
                //foreach (var pair in edgedists[center].Take((int)(s * 1.5))) {
                //    nearby.Add(edge[pair.Index]);
                //    edge_vi[pair.Index] = true;
                //}
                //nearby = nearby.Sample(s);
                for (int wd = 0; wd < windowcount; ++wd) {
                    #region 滑动窗口位置
                    //int window_center = wd * windowstep + (windowwidth / 2);
                    double window_center = (wd * 2 + overlap / 2.0) * slice_width;
                    g.DrawLine(Pens.Green, (float)window_center, 0, (float)window_center, img.Height);
                    var nearby = edge.Where(p => Math.Abs(p.X - window_center) < img.Height)
                                     .OrderBy(p => Math.Abs(p.X - window_center))
                                     .Take((int)(s * 1.2))
                                     .ToList().Sample(s);
                    if (nearby.Average(p => Math.Abs(p.X - window_center)) > img.Height) continue;
                    var sc = Jim.OCR.ShapeContext2D.ShapeContext.ComputeSC2(nearby);

                    #endregion

                    #region 对待测图的形状上下文进行量化

                    int[] histogram = new int[K];
                    for (int i = 0; i < s; ++i) {
                        double[] ds = new double[K];
                        for (int j = 0; j < K; ++j)
                            ds[j] = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(sc[i], shapemes[j]);
                        int id = ds.Select((v, idx) => new ValueIndexPair<double> { Value = v, Index = idx })
                            .OrderBy(p => p.Value)
                            .First().Index;
                        ++histogram[id];
                    }

                    #endregion

                    #region 计算量化后的比较距离

                    double[] dists = new double[templatecount];
                    for (int i = 0; i < templatecount; ++i) {
                        //dists[i] = Jim.OCR.ShapeContext2D.ShapeContext.ChiSquareDistance(histogram, templatehistograms[i]);
                        dists[i] = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(
                            histogram.Select(d => (double)d).ToArray(),
                            templatehistograms[i].Select(d => (double)d).ToArray());
                    }

                    #endregion

                    #region 对结果进行排序和统计

                    var arr = dists.Select((d, i) => new ValueIndexPair<double> { Value = d, Index = i })
                        .OrderBy(p => p.Value)
                        .Select(p => new { Distance = p.Value, Char = templatechars[p.Index] })
                        .Where(p => "0123456789".IndexOf(p.Char) != -1)
                        .ToArray();
                    Dictionary<string, int> matchcount = new Dictionary<string, int>();
                    int knn = 10;
                    foreach (var pair in arr.Take(knn)) {
                        string ch = pair.Char;
                        matchcount[ch] = matchcount.ContainsKey(ch) ? matchcount[ch] + 1 : 1;
                    }
                    var match = matchcount.Select(pair => new { Count = pair.Value, Ch = pair.Key })
                        .Where(v => v.Count > 0)
                        .OrderByDescending(v => v.Count).ToArray();
                    var firstmatch = match[0];
                    PointF newcenter = new PointF(nearby.Average(p => (float)p.X), nearby.Average(p => (float)p.Y));
                    charlist.Add(new Tuple<string, int, PointF> {
                        First = firstmatch.Ch,
                        Second = firstmatch.Count,
                        Third = newcenter
                    });

                    #endregion
                }
                foreach (var tp in charlist) {
                    string ch = tp.First;
                    int acc = tp.Second;
                    PointF center = tp.Third;
                    //g.DrawString(num.ToString(), new Font("Arial", 24), new SolidBrush(Color.FromArgb(40 + 20 * acc, 0, 0)),
                    //            new PointF(center.X - 12, center.Y - 12));
                    g.DrawString(ch, new Font("Arial", 24), (acc >= 5 ? Brushes.Red : Brushes.DarkGreen),
                                new PointF(center.X - 12, center.Y - 12));
                }
                mmp.Save(Path.Combine(@"D:\Play Data\测试玩意\", filename + ".jpg"));
                Debug("{0}-{1}ms", filename, timer.Stop());

            }
            #endregion
        }
Esempio n. 11
0
        private static void quantizeSC()
        {
            MyTimer timer = new MyTimer();
            int s = 100, K = 100, m = 180;
            string[] templatefiles = Directory.GetFiles(@"D:\Play Data\my_template_data\sc\", "*.sc")
                .Skip(0).Take(1000).ToArray();
            int templatecount = templatefiles.Length;

            #region 打开Shapeme
            Debug("打开{0}个Shapeme.", K);
            timer.Restart();
            double[][] shapemes = new double[K][];
            using (var fs = new FileStream(Path.Combine(@"D:\Play Data\my_template_data\sm-" + K, m + ".sm"), FileMode.Open)) {
                using (var br = new BinaryReader(fs)) {
                    for (int i = 0; i < K; ++i) {
                        shapemes[i] = new double[60];
                        for (int k = 0; k < 60; ++k) {
                            shapemes[i][k] = br.ReadDouble();
                        }
                    }
                }
            }
            Debug("Shapeme读取完成,用时{0}ms.", timer.Stop());
            #endregion

            #region 读取模板和量化
            Debug("对{0}个模板进行量化--------------------------------------------", templatecount);
            timer.Restart();
            for (int f = 0; f < templatecount; ++f) {
                string file = templatefiles[f];
                string filename = Path.GetFileNameWithoutExtension(file);

                int[] histogram = new int[K];
                using (var fs = new FileStream(file, FileMode.Open)) {
                    using (var br = new BinaryReader(fs)) {
                        for (int j = 0; j < s; ++j) {
                            double[] sc = new double[60];
                            for (int k = 0; k < 60; ++k) {
                                sc[k] = br.ReadDouble();
                            }

                            double[] dists = new double[K];
                            for (int k = 0; k < K; ++k)
                                dists[k] = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(sc, shapemes[k]);
                            int id = dists.Select((v, idx) => new ValueIndexPair<double> { Value = v, Index = idx })
                                          .OrderBy(p => p.Value)
                                          .First().Index;
                            ++histogram[id];
                        }
                    }
                }
                using (var fs = new FileStream(Path.Combine(@"D:\Play Data\my_template_data\scq-" + K + "-" + m, filename + ".scq"), FileMode.Create)) {
                    using (var bw = new BinaryWriter(fs)) {
                        for (int i = 0; i < K; ++i) {
                            bw.Write(histogram[i]);
                        }
                    }
                }

                if (f % 100 == 0)
                    Debug("已完成{0}个", f);
            }
            Debug("量化完成,用时{0}ms.", timer.Stop());
            #endregion
        }
Esempio n. 12
0
        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)));
        }
Esempio n. 13
0
        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;
        }
Esempio n. 14
0
        private void gao()
        {
            clearText();
            string filename = label1.Text;
            string path     = Path.GetDirectoryName(filename);
            string file     = Path.GetFileNameWithoutExtension(filename);
            string savepath = Path.Combine(path, "out");

            appendLine(filename);

            Image <Bgr, Byte> bmp = new Image <Bgr, byte>(filename);

            Image <Gray, Byte> gray = bmp.Convert <Gray, Byte>();

            double threshold = new MaxVarianceBinarization().CalculateThreshold(gray);

            appendLine("阈值:{0}", threshold);

            //Image<Gray, Byte> bi = gray.ThresholdBinaryInv(new Gray(threshold), new Gray(255));
            // Image<Gray, Byte> dn = bi.SmoothMedian(3);
            int it;

            //Stopwatch timer = Stopwatch.StartNew();
            //Image<Gray, Byte> dn = new AnnealKMeansClusterDenoise().Denoise(bi, 1, out it);
            //timer.Stop();
            //appendLine("降噪用时{0}ms,迭代次数{1}。", timer.ElapsedMilliseconds, it);

            //var con = dn.FindContours();
            //bmp.Draw(con, new Bgr(0, 0, 255), new Bgr(255, 0, 0), 1, 1);

            //var proj = Projecting.VerticalProject(dn);
            //var proj = bi.SmoothMedian(3);

            //var proj = dn - dn.Erode(1);//dn.Dilate(1) - bi;

            //var proj = gray.MorphologyEx(see, Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_OPEN, 1);
            //var proj =
            //showImage(imageBox1, bi);
            //showImage(imageBox2, dn);
            //showImage(imageBox1, gray);

            //showImage(imageBox1, gray);

            timer.Restart();
            var mask = gray.SmoothMask();

            showImage(imageBox1, mask);
            appendLine("掩模:{0}ms", timer.Stop());

            timer.Restart();
            double thr  = new MaxVarianceBinarization().CalculateThreshold(mask);
            var    thrd = mask.ThresholdBinaryInv(new Gray(thr), new Gray(255));

            showImage(imageBox2, thrd);
            appendLine("二值:{0}ms", timer.Stop());

            timer.Restart();
            var smooth = thrd.SmoothMedian(7);

            showImage(imageBox3, smooth);
            appendLine("中值滤波:{0}ms", timer.Stop());

            timer.Restart();
            var dm = new AnnealKMeansClusterDenoise().Denoise(thrd, 0, out it).SmoothMedian(5);

            showImage(imageBox4, dm);
            appendLine("区域联通:{0}ms", timer.Stop());

            #region 灰度分级连通
            //int level = 16;
            //var gray4 = mask.ToGrayN(level);
            //showImage(imageBox1, gray4);

            //timer.Restart();
            //var conns = gray4.Connect(level);
            //appendLine("分级:{0}ms", timer.Stop());

            //var mins = Utils.FindLocalMins(conns.Select(c => c.Domains.Count).ToArray());
            //var list = new List<ConnectLevel>();
            //for (int i = 1; i < mins.Length; ++i) {
            //    var cl = conns[mins[i]];
            //    if (cl.Domains.Count == 1) continue;
            //    if (cl.MeanArea < 10) continue;
            //    if (cl.Variance > 20000) continue;
            //    //if (mins[i] - mins[i - 1] == 1) {
            //    //    var lastcl = conns[mins[i] - 1];
            //    //    if (lastcl.Domains.Count != cl.Domains.Count)
            //    //        list.Add(cl);
            //    //} else {
            //    //    list.Add(cl);
            //    //}
            //    list.Add(cl);
            //}
            //list.ForEach(
            //    c => appendLine("Lv{0},C{1},MA{2:F2},VA{3:F4}", c.Level, c.Domains.Count, c.MeanArea, c.Variance));
            //timer.Restart();
            //var bestlevel = list.OrderByDescending(c => c.MeanArea).ThenBy(c => c.Domains.Count).First();
            //var colored = gray4.ColorLevel(bestlevel);
            //var see = new StructuringElementEx(4, 4, 1, 1, Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_ELLIPSE);
            //var bg = colored.Erode(10).Dilate(10);
            //showImage(imageBox2, colored - bg);
            //appendLine("染色处理{0}ms", timer.Stop());

            #endregion

            //double t2=new MaxVarianceBinarization().CalculateThreshold(mask);
            //var proj = mask.ThresholdBinaryInv(new Gray(t2), new Gray(255));
            //var akmcd = new AnnealKMeansClusterDenoise();
            //var t3 = new MaxVarianceBinarization().CalculateThreshold(mask);
            //var bi2 = mask.ThresholdBinaryInv(new Gray(t3), new Gray(255));
            //showImage(imageBox2, bi2);

            //var dn2 = akmcd.Denoise(bi2, 1, out it);
            //showImage(imageBox3, dn2);

            //var contour = ContourFinder.ColorContours(dn2, new Gray(0), new Gray(255));
            //showImage(imageBox5, contour);

            //var con = dn2.FindContours();
            //var con2 = dn2.Convert<Bgr, Byte>();
            //con2.Draw(con, new Bgr(0, 0, 255), new Bgr(0, 255, 0), 1, 1);
            //showImage(imageBox6, con2);

            //p1 = akmcd.Denoise(p1, 0, out it);
            //p2 = akmcd.Denoise(p2, 0, out it);
            //var p3 = p1.Xor(p2);
            //var p4 = p1 - p3;
            //var p5 = p2 - p3;
            //var p6 = p1 - p2;

            //var p4 = akmcd.Denoise(p1, 0, out it);
            //var p5 = akmcd.Denoise(p2, 0, out it);
            //var p6 = akmcd.Denoise(p3, 0, out it);

            //StructuringElementEx se = new StructuringElementEx(3, 3, 1, 1, Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_RECT);

            //dn = dn.MorphologyEx(se, Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_OPEN, 1);

            //var canny = dn.Canny(new Gray(threshold), new Gray(threshold * 0.6));

            //showImage(imageBox1, bmp);
            //showImage(imageBox2, gray);
            //showImage(imageBox3, bi);
            //showImage(imageBox4, dn);
            //showImage(imageBox5, p1);
            //showImage(imageBox6, p2);
            //showImage(imageBox4, p4);
            //showImage(imageBox5, p5);
            //showImage(imageBox6, p6);
        }
Esempio n. 15
0
        private static void fastPruningWithShapeme()
        {
            var timer = new MyTimer();
            int s = 100, K = 100, m = 100;

            string[] templatefiles = Directory.GetFiles(@"D:\Play Data\train_data\scq-" + K + "-" + m, "*.scq")
                .Take(20000).ToArray();
            #region 打开量化的模板
            int templatecount = templatefiles.Length;
            Debug("打开{0}个量化模板----------------------------------------", templatecount);
            timer.Restart();
            int[][] templatehistograms = new int[templatecount][];
            int[] templatenums = new int[templatecount];
            for (int f = 0; f < templatecount; ++f) {
                string file = templatefiles[f];
                string filename = Path.GetFileNameWithoutExtension(file);
                templatenums[f] = int.Parse(filename.Split('-')[1]);
                templatehistograms[f] = new int[K];
                using (var fs = new FileStream(file, FileMode.Open)) {
                    using (var br = new BinaryReader(fs)) {
                        for (int i = 0; i < K; ++i) {
                            templatehistograms[f][i] = br.ReadInt32();
                        }
                    }
                }
            }
            Debug("打开完成,用时{0}ms.", timer.Stop());

            #endregion

            #region 打开Shapeme
            Debug("打开{0}个Shapeme.", K);
            timer.Restart();
            double[][] shapemes = new double[K][];
            using (var fs = new FileStream(Path.Combine(@"D:\Play Data\train_data\sm-" + K, m + ".sm"), FileMode.Open)) {
                using (var br = new BinaryReader(fs)) {
                    for (int i = 0; i < K; ++i) {
                        shapemes[i] = new double[60];
                        for (int k = 0; k < 60; ++k) {
                            shapemes[i][k] = br.ReadDouble();
                        }
                    }
                }
            }

            Debug("Shapeme读取完成,用时{0}ms.", timer.Stop());
            #endregion

            string[] testfiles = Directory.GetFiles(@"D:\Play Data\test\", "*.bmp")
                .Take(1000).ToArray();
            #region 测试
            int testcase = testfiles.Length, acc = 0;
            Debug("为{0}个对象寻找候选模板------------------------------------------", testcase);
            foreach (var file in testfiles) {
                timer.Restart();
                #region 计算待测图的形状上下文
                string filenameext = Path.GetFileName(file);
                string filename = Path.GetFileNameWithoutExtension(file);
                int thisnum = int.Parse(filename.Split('-')[1]);
                Image<Gray, Byte> img = new Image<Gray, byte>(file);
                var list = getEdge(img.Resize(2.5, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR)).Sample(s);
                var sc = Jim.OCR.ShapeContext2D.ShapeContext.ComputeSC2(list);
                #endregion

                #region 对待测图的形状上下文进行量化
                int[] histogram = new int[K];
                for (int i = 0; i < s; ++i) {
                    double[] ds = new double[K];
                    for (int j = 0; j < K; ++j)
                        ds[j] = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(sc[i], shapemes[j]);
                    int id = ds.Select((v, idx) => new ValueIndexPair<double> { Value = v, Index = idx })
                                  .OrderBy(p => p.Value)
                                  .First().Index;
                    ++histogram[id];
                }
                #endregion

                #region 计算量化后的比较距离
                double[] dists = new double[templatecount];
                for (int i = 0; i < templatecount; ++i) {
                    dists[i] = Jim.OCR.ShapeContext2D.ShapeContext.ChiSquareDistance(histogram, templatehistograms[i]);
                    //dists[i] = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(histogram.Cast<double>().ToArray(), templatehistograms[i].Cast<double>().ToArray());
                }
                #endregion

                #region 对结果进行排序和统计
                var arr = dists.Select((d, i) => new ValueIndexPair<double> { Value = d, Index = i })
                                 .OrderBy(p => p.Value)
                                 .Select(p => new { Distance = p.Value, Num = templatenums[p.Index] })
                                 .ToArray();
                int[] matchcount = new int[10];
                int knn = 10;
                foreach (var pair in arr.Take(knn)) {
                    int num = pair.Num;
                    matchcount[num]++;
                }
                var match = matchcount.Select((val, i) => new { Count = val, Num = i })
                                      .Where(v => v.Count > 0)
                                      .OrderByDescending(v => v.Count).ToArray();
                #endregion

                int firstmatch = match[0].Num;
                var fc = Console.ForegroundColor;
                Console.ForegroundColor = firstmatch == thisnum ? ConsoleColor.Green : ConsoleColor.Red;
                string info = String.Format("{0} {1}ms - {2}\t", filename, timer.Stop(), (firstmatch == thisnum ? "Right" : "Wrong"));
                foreach (var ma in match.Take(4)) {
                    info += String.Format("{0}/{1}\t", ma.Num, ma.Count);
                }
                Debug(info);
                Console.ForegroundColor = fc;

                if (firstmatch == thisnum) {
                    ++acc;
                }
            }
            Debug("测试用例:{0}。正确率{1}。", testcase, acc);
            #endregion
        }
Esempio n. 16
0
        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);
        }
Esempio n. 17
0
        private static void testCluter()
        {
            int ss = 100, sq = 100, k = 10, m = 10; // 采样数,G取前k,S取前m
            int randcount = 5, randtake = 10, randselect = 3;
            var timer = new MyTimer();
            var templatefiles = Directory.GetFiles(@"D:\Play Data\字符模板");
            int templatecount = templatefiles.Length;
            var templateChars = new string[templatecount];
            var templatePoints = new Vector2[templatecount][];
            //var templatesc = new double[templatecount][,];
            var templatesc = new double[templatecount][][];
            #region 计算模板的SC
            for (int f = 0; f < templatecount; ++f) {
                string file = templatefiles[f], filename = Path.GetFileNameWithoutExtension(file);
                using (Image<Gray, Byte> img = new Image<Gray, byte>(file)) {
                    var samples = getEdge(img).Sample(ss);
                    templatesc[f] = Jim.OCR.ShapeContext2D.ShapeContext.ComputeSC2(samples);
                    templatePoints[f] = samples.Select(p => new Vector2(p.X, p.Y)).ToArray();
                }
                templateChars[f] = filename;
                Console.Write(filename);
            }
            Console.WriteLine();
            Debug("模板读取完成");
            #endregion

            #region 处理字符
            foreach (string file in Directory.GetFiles(@"D:\Play Data\字符")) {
                string filename = Path.GetFileNameWithoutExtension(file);
                if (filename != "AB") continue;
                timer.Restart();
                Image<Bgr, Byte> img = new Image<Bgr, Byte>(file);
                var samples = getEdge(img.Convert<Gray, Byte>()).Sample(sq);
                //double[,] SCQ = Jim.OCR.ShapeContext2D.ShapeContext.ComputeSC(samples);
                double[][] SCQ = Jim.OCR.ShapeContext2D.ShapeContext.ComputeSC2(samples);
                var Q_Points = samples.Select(p => new Vector2(p.X, p.Y)).ToArray();
                var mmg = img.Convert<Bgr, Byte>();
                Graphics g = Graphics.FromImage(mmg.Bitmap);
                Q_Points.ToList().ForEach(v => { mmg[(int)v.Y, (int)v.X] = new Bgr(0, 0, 255); });

                var point_distance = new ValueIndexPair<double>[sq][];
                #region 计算采样点之间的距离
                for (int i = 0; i < sq; ++i) {
                    double xi = Q_Points[i].X, yi = Q_Points[i].Y;
                    point_distance[i] = new ValueIndexPair<double>[sq];
                    for (int j = 0; j < sq; ++j) {
                        double xj = Q_Points[j].X, yj = Q_Points[j].Y;
                        point_distance[i][j] = new ValueIndexPair<double> {
                            Value = Math.Sqrt((xi - xj) * (xi - xj) + (yi - yj) * (yi - yj)),
                            Index = j
                        };
                    }
                    Array.Sort(point_distance[i], (a, b) => a.Value.CompareTo(b.Value));
                }
                #endregion
                var randpoints = new int[randcount][];
                #region 随机取randcount个点,并在其周围randtake个点中取randselect个
                for (int i = 0; i < randcount; ++i) {
                    int pi = rand.Next(Q_Points.Length);
                    var p = Q_Points[pi];
                    mmg.Draw(new CircleF(new PointF((float)p.X, (float)p.Y), 2), new Bgr(255, 0, 0), 1);

                    randpoints[i] = new int[randselect];
                    bool[] vi = Utils.InitArray<bool>(randtake, false);
                    for (int cnt = 0; cnt < randselect; ) {
                        int rnd = rand.Next(randtake);
                        if (!vi[rnd]) {
                            vi[rnd] = true;
                            randpoints[i][cnt++] = rnd;
                        }
                    }
                    for (int ppp = 0; ppp < randselect; ++ppp) {
                        var pt = Q_Points[point_distance[pi][randpoints[i][ppp]].Index];
                        //g.DrawString(i.ToString(), new Font("Arial", 7), new SolidBrush(Color.FromArgb(0, 128, 0)), new PointF((float)pt.X, (float)pt.Y));
                    }
                }
                #endregion
                #region 为这randcount组RSC分别选最好的模板
                var rscmatch = new Tuple<int, double, Vector2>[randcount]; // <Si, d, L>
                for (int rc = 0; rc < randcount; ++rc) {
                    var rsc_matches = new Tuple<double, Vector2>[templatecount]; // <d, L>
                    for (int i = 0; i < templatecount; ++i) {
                        #region 拷贝出一个rsc来
                        var rsc = new double[randselect][];
                        for (int j = 0; j < randselect; ++j) {
                            rsc[j] = new double[60];
                            Array.Copy(SCQ[randpoints[rc][j]], rsc[j], 60);
                        }
                        #endregion
                        var costmat = Jim.OCR.ShapeContext2D.ShapeContext.HistCost2(rsc, templatesc[i]);
                        var matches = costmat.Select(
                            row => row.Select((d, c) => new ValueIndexPair<double> { Value = d, Index = c })
                                      .OrderBy(d => d.Value).First()).ToArray();
                        Vector2 L = Vector2.Zero;
                        double M = 0;
                        for (int j = 0; j < randselect; ++j) {
                            int u = randpoints[rc][j], mu = matches[j].Index;
                            double d = matches[j].Value;
                            Vector2 pu = Q_Points[u], pmu = templatePoints[i][mu];
                            M += (1 - d);
                            L += (1 - d) * (pu - pmu);
                        }
                        L /= M;

                        rsc_matches[i] = new Tuple<double, Vector2> {
                            First = matches.Sum(r => r.Value),
                            Second = L
                        };
                    }
                    var best_template = rsc_matches.Select((mt, i) => new { Match = mt, i })
                                                   .OrderBy(t => t.Match.First)
                                                   .First();
                    rscmatch[rc] = new Tuple<int, double, Vector2> {
                        First = best_template.i,
                        Second = best_template.Match.First,
                        Third = best_template.Match.Second
                    };

                    string label = templateChars[best_template.i];
                    g.DrawString(label, new Font("Arial", 48), Brushes.Green,
                                 new PointF((float)best_template.Match.Second.X, (float)best_template.Match.Second.Y));
                }
                #endregion

                //Font f = new Font("Arial", 12);
                //var G = new Tuple<int, int, double>[templatecount][]; // <u, m(u), d>
                //#region 为每个Si挑选合适的Gi
                //{
                //    var costmats = new double[templatecount][,];
                //    for (int i = 0; i < templatecount; ++i) {
                //        double[,] SCi = templatesc[i];
                //        costmats[i] = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(SCQ, SCi);
                //        G[i] = new Tuple<int, int, double>[sq * ss];
                //        for (int u = 0; u < sq; ++u) {
                //            for (int j = 0; j < ss; ++j) {
                //                G[i][u * ss + j] = new Tuple<int, int, double> {
                //                    First = u,
                //                    Second = j,
                //                    Third = costmats[i][u, j]
                //                };
                //            }
                //        }
                //        Array.Sort(G[i], (da, db) => da.Third.CompareTo(db.Third));
                //    }
                //}
                //#endregion
                //var d_Q_S = new double[templatecount];
                //#region 求出每个Si和Q的d(Q, Si)
                //{
                //    for (int i = 0; i < templatecount; ++i) {
                //        var Gi = G[i].Take(k);
                //        foreach (var g in Gi) {
                //            int u = g.First, mu = g.Second;
                //            double d = g.Third;
                //            double Nu = G.Average(gi => gi.First(t => t.First == u).Third);
                //            d_Q_S[i] += d / Nu;
                //        }
                //        d_Q_S[i] /= k;
                //    }
                //}
                //#endregion
                //var firstmG = new Tuple<Tuple<int, int, double>[], double, int>[m]; // <G, d, i> <=> <<u, m(u), d>[], d, i>
                //#region 根据d(Q, Si)截取前20个最好的Gi
                //{
                //    var firstmdQS = d_Q_S.Select((d, i) => new ValueIndexPair<double> { Value = d, Index = i })
                //        .OrderBy(p => p.Value)
                //        .Take(firstmG.Length).ToArray();
                //    for (int p = 0; p < firstmG.Length; ++p) {
                //        double d = firstmdQS[p].Value;
                //        int i = firstmdQS[p].Index;
                //        firstmG[p] = new Tuple<Tuple<int, int, double>[], double, int> {
                //            First = G[i].Take(k).ToArray(),
                //            Second = d,
                //            Third = i
                //        };
                //    }
                //}
                //#endregion
                //#region 计算每个G的位置
                //var L = new Vector2[m];
                //{
                //    for (int i = 0; i < m; ++i) {
                //        L[i] = Vector2.Zero;
                //        double Mi = 0;
                //        var Gi = firstmG[i];
                //        foreach (var u_mu_d in Gi.First) {
                //            int u = u_mu_d.First, mu = u_mu_d.Second;
                //            double d = u_mu_d.Third;
                //            Vector2 pu = Q_Points[u], pmu = templatePoints[Gi.Third][mu];
                //            L[i] += (1 - d) * (pu - pmu);
                //            Mi += (1 - d);
                //        }
                //        L[i] /= Mi;

                //        g.DrawString(templateChars[Gi.Third], new Font("Arial", 12), Brushes.Green,
                //                     new PointF((float)L[i].X, (float)L[i].Y));
                //    }
                //}
                //#endregion
                mmg.Save(Path.Combine(@"D:\Play Data\测试玩意", filename + ".bmp"));
                Debug("{0}\t用时{1}ms.", filename, timer.Stop());
            }
            #endregion
        }