예제 #1
0
        public Tuple<string, int> Recognize(Image<Gray, byte> src)
        {
            var list = src.getEdge().Sample(100);

            #region 计算形状上下文
            int r = 15;
            var scall = Jim.OCR.ShapeContext2D.ShapeContext.ComputeSC(list);
            var scq = new double[r, 60];
            for (int i = 0; i < r; ++i) {
                int pos = rand.Next(list.Count);
                for (int k = 0; k < 60; ++k) {
                    scq[i, k] = scall[pos, k];
                }
            }
            #endregion
            #region 计算距离
            var dists = new ValueIndexPair<double>[SC.template_sc.Length];
            for (int i = 0; i < SC.template_sc.Length; ++i) {
                double[,] sci = SC.template_sc[i];
                double[,] costmat = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(scq, sci);
                double cost = 0;
                for (int j = 0; j < r; ++j) {
                    double min = double.MaxValue;
                    for (int u = 0; u < 100; ++u) {
                        double val = costmat[j, u];
                        if (val < min) min = val;
                    }
                    cost += min;
                }
                dists[i] = new ValueIndexPair<double> { Value = cost, Index = i };
            }
            #endregion

            #region 对结果排序
            var arr = dists
                .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 };
        }
예제 #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 };
        }