Beispiel #1
0
        private void recognize_shapeme()
        {
            if (template_histograms == null)
            {
                MessageBox.Show("尚未读取模板。");
                return;
            }
            new Thread(new ThreadStart(() => {
                clearLog();
                showStatus("搜索中");
                foreach (var challenge in splitted_chars)
                {
                    timer.Restart();
                    var list = challenge.getEdge().Sample(100);
                    var sc   = ShapeContext.ComputeSC2(list);
                    if (sc.Length < 100)
                    {
                        var tmp = new double[100][];
                        for (int i = 0; i < 100; ++i)
                        {
                            tmp[i] = new double[60];
                        }
                        for (int i = 0; i < sc.Length; ++i)
                        {
                            Array.Copy(sc[i], tmp[i], 60);
                        }
                        sc = tmp;
                    }

                    #region 量化到shapeme
                    int[] histogram = new int[100];
                    for (int i = 0; i < 100; ++i)
                    {
                        double[] ds = new double[100];
                        for (int j = 0; j < 100; ++j)
                        {
                            ds[j] = 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[template_histograms.Length];
                    for (int i = 0; i < template_histograms.Length; ++i)
                    {
                        dists[i] = Jim.OCR.ShapeContext2D.ShapeContext.ChiSquareDistance(histogram, template_histograms[i]);
                        //dists[i] = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(histogram.Cast<double>().ToArray(), templatehistograms[i].Cast<double>().ToArray());
                        showProgress((i + 1.0) / template_histograms.Length);
                    }
                    #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 = template_chars[p.Index] })
                              //.Where(p => "ABCDEFGHIJKLMNPQRSTUVWXYZ123456789".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();
                    string result = "";
                    foreach (var m in match.Take(3))
                    {
                        result += String.Format("Char:'{0}',Accuracy:{1}/{2}\t", m.Ch, m.Count, knn);
                    }
                    appendLine(result);
                    #endregion
                }
                appendLine("-----------------------------------------------------");
                showStatus("搜索完成,共用时{0}ms。", timer.Stop());
            })).Start();
        }
Beispiel #2
0
        public Tuple <string, int> Recognize(Image <Gray, byte> challenge)
        {
            var list = challenge.getEdge().Sample(100);
            var sc   = ShapeContext.ComputeSC2(list);

            if (sc.Length < 100)
            {
                var tmp = new double[100][];
                for (int i = 0; i < 100; ++i)
                {
                    tmp[i] = new double[60];
                }
                for (int i = 0; i < sc.Length; ++i)
                {
                    Array.Copy(sc[i], tmp[i], 60);
                }
                sc = tmp;
            }

            #region 量化到shapeme
            int[] histogram = new int[100];
            for (int i = 0; i < 100; ++i)
            {
                double[] ds = new double[100];
                for (int j = 0; j < 100; ++j)
                {
                    ds[j] = ShapeContext.HistCost(sc[i], SC.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[SC.template_histograms.Length];
            for (int i = 0; i < SC.template_histograms.Length; ++i)
            {
                dists[i] = Jim.OCR.ShapeContext2D.ShapeContext.ChiSquareDistance(histogram, SC.template_histograms[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, Char = SC.template_chars[p.Index] })
                      //.Where(p => "ABCDEFGHIJKLMNPQRSTUVWXYZ123456789".IndexOf(p.Char) != -1)
                      .Where(p => Filter.IndexOf(p.Char) != -1)
                      .ToArray();
            Dictionary <string, int> matchcount = new Dictionary <string, int>();
            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();
            //string result = "";
            //foreach (var m in match.Take(3)) {
            //    result += String.Format("Char:'{0}',Accuracy:{1}/{2}\t", m.Ch, m.Count, Knn);
            //}
            #endregion

            return(new Tuple <string, int> {
                First = match[0].Ch, Second = match[0].Count
            });
        }