Пример #1
0
        public void BoundsTest()
        {
            EulerMonomap2D euler    = new EulerMonomap2D("30,30,30,30,30,30,30,30,30,30,30,30,30,30,30");
            var            hashCode = euler.GetHashCode();

            Assert.IsTrue(true);
        }
Пример #2
0
        public void NotEqualHashsTest()
        {
            EulerMonomap2D euler1 = new EulerMonomap2D("1,0,1,0,1,0,1,0,1,0,1,0,1,0,1");
            EulerMonomap2D euler2 = new EulerMonomap2D("0,1,0,1,0,1,0,1,0,1,0,1,0,1,0");

            Assert.AreNotEqual(euler1.GetHashCode(), euler2.GetHashCode());
        }
Пример #3
0
        /// <summary>
        /// Создание экземпляра класса <see cref="SymbolCode"/>.
        /// </summary>
        public SymbolCode(int height, EulerMonomap2D eulerCode)
        {
            if (height <= 0)
            {
                throw new ArgumentException(nameof(height));
            }

            EulerCode = eulerCode;
            Height    = height;
        }
Пример #4
0
        private bool TryIntelliRecognition(
            Symbol possibleSymbol,
            EulerMonomap2D currentCharEuler,
            int height,
            out QChar @char)
        {
            @char = null;

            // TODO дорогое вычисление, пока тестовый вариант

            /*
             * Анализировать:
             * 1. Equals
             * 2. -1 < X < 1
             * 3. Количество совпадений в базе знаний что бы не опираться на косячный шрифт.
             */
            var possibleSybols = possibleSymbol.Codes.Select(
                code =>
            {
                int rounding, equals;
                _comparer.Compare(code.EulerCode, currentCharEuler, out rounding, out equals);
                return(new { EulerEquals = equals, EulerRounding = rounding });
            })

                                 // TODO Как минимум половина набора совпадает (Стоит играться)
                                 .Where(result => result.EulerEquals >= _comparer.RoundingLimit).ToArray();

            if (!possibleSybols.Any())
            {
                return(false);
            }

            var bestValue = possibleSybols[0];

            foreach (var possibleSybol in possibleSybols)
            {
                if (possibleSybol.EulerRounding > bestValue.EulerRounding)
                {
                    bestValue = possibleSybol;
                }
            }

            @char = new QChar(possibleSymbol.Chr, QState.Assumptions, bestValue.EulerEquals, bestValue.EulerRounding, possibleSybols.Length);
            return(true);
        }
Пример #5
0
        /// <inheritdoc/>
        void IEulerComparer.Compare(EulerMonomap2D euler1, EulerMonomap2D euler2, out int rounding, out int equals)
        {
            // Количество очень близких значений в интервале
            rounding = 0;

            // Количество полных совпадений
            equals = 0;

            ComputeDiff(euler1.S0, euler2.S0, ref rounding, ref equals);
            ComputeDiff(euler1.S1, euler2.S1, ref rounding, ref equals);
            ComputeDiff(euler1.S2, euler2.S2, ref rounding, ref equals);
            ComputeDiff(euler1.S3, euler2.S3, ref rounding, ref equals);
            ComputeDiff(euler1.S4, euler2.S4, ref rounding, ref equals);
            ComputeDiff(euler1.S5, euler2.S5, ref rounding, ref equals);
            ComputeDiff(euler1.S6, euler2.S6, ref rounding, ref equals);
            ComputeDiff(euler1.S7, euler2.S7, ref rounding, ref equals);
            ComputeDiff(euler1.S8, euler2.S8, ref rounding, ref equals);
            ComputeDiff(euler1.S9, euler2.S9, ref rounding, ref equals);
            ComputeDiff(euler1.S10, euler2.S10, ref rounding, ref equals);
            ComputeDiff(euler1.S11, euler2.S11, ref rounding, ref equals);
            ComputeDiff(euler1.S12, euler2.S12, ref rounding, ref equals);
            ComputeDiff(euler1.S13, euler2.S13, ref rounding, ref equals);
            ComputeDiff(euler1.S14, euler2.S14, ref rounding, ref equals);
        }
Пример #6
0
 /// <summary>
 /// Создание экземпляра класса <see cref="QSymbol"/>.
 /// </summary>
 public QSymbol(IMonomap monomap, Point startPoint, EulerMonomap2D euler)
 {
     Euler      = euler;
     Monomap    = monomap;
     StartPoint = startPoint;
 }
Пример #7
0
        /// <inheritdoc/>
        public QAnalyzedSymbol AnalyzeFragment(
            QSymbol currentFragment,
            IEnumerable <QSymbol> unknownFragments,
            IProducerConsumerCollection <QAnalyzedSymbol> recognizedSymbols)
        {
            /*
             * Алгоритм работы.
             * P.S. Мы работаем со 100% не известным символом, либо фрагментом символа.
             *
             *
             * Input1: ip
             * Input2: Red Alert
             *  сначала будет R потом A затем l.
             *  e, d будут подмяты затем на e, r будет сплющивание вектора
             *
             * Input3: iiа  результат при анализе ii они сольются
             */

            // TODO Позже к высоте можно привязываться
            const int DefaultSplitStep         = 3;
            var       currentFragmentMinVector = currentFragment.StartPoint.Y + DefaultSplitStep;

            // Распознанные символы, лежащие в диапазоне поиска
            var currentLineRecognizedChars =
                recognizedSymbols.Where(
                    symbol =>
                    symbol.StartPoint.Y <= currentFragmentMinVector &&
                    currentFragmentMinVector <= symbol.StartPoint.Y + symbol.Height).ToArray();

            Point bottomRightPoint;

            if (currentLineRecognizedChars.Any())
            {
                var lineChars = currentLineRecognizedChars.ToDictionary(
                    symbol => symbol,
                    symbol => symbol.StartPoint.Y + symbol.Height);

                var lowestBound  = lineChars.Values.Max();
                var lowestSymbol = lineChars.First(symbol => symbol.Value == lowestBound);

                // Минимальная нижняя точка для текущей линии для распознанных символов
                var minLineY = currentFragment.StartPoint.Y + lowestSymbol.Key.Height;

                bottomRightPoint = new Point(
                    currentFragment.StartPoint.X + currentFragment.Width,
                    minLineY);
            }
            else
            {
                // Нижняя правая точка будет ширина фрагмента.
                bottomRightPoint = new Point(
                    currentFragment.StartPoint.X + currentFragment.Width,
                    currentFragment.StartPoint.Y + currentFragment.Height + _minimalHeight);
            }

            // Мерджим фрагменты которые лежат в прямоугольнике fragment.StartPoint > ! > bottomRightPoint
            QSymbol[] mergedFragments = unknownFragments.Where(
                fragment => IsFragmentInsideSquare(fragment, currentFragment.StartPoint, bottomRightPoint))
                                        .ToArray();

            EulerMonomap2D currentEuler = EulerMonomap2D.Empty;

            currentEuler = mergedFragments.Select(fragment => fragment.Euler)
                           .Aggregate(currentEuler, (current, mergedEuler) => current + mergedEuler);

            QAnalyzedSymbol analyzedSymbol;

            if (TryFindSymbol(currentFragment, out analyzedSymbol))
            {
                recognizedSymbols.TryAdd(analyzedSymbol);

                // TODO Symbol стоит смержить, но после всех манипуляций!! Саму картинку
                currentFragment = currentFragment;

                return(analyzedSymbol);
            }

            // Результат анализа всех букв !!!
            var resultData = new List <QChar>();

            // Идём по всем буквам языка
            foreach (var possibleSymbol in _knownSymbols)
            {
                QChar @char;
                if (TryIntelliRecognition(
                        possibleSymbol,
                        currentEuler,
                        bottomRightPoint.Y - currentFragment.StartPoint.Y,
                        out @char) && @char.Popularity > _comparer.MinPopularity)
                {
                    // Не стоит пропускать проверку всех символов, так как стоит найти 3 и з цифро-буквы, либо аналоги А ру. и а англ.
                    resultData.Add(@char);
                }
            }

            return(new QAnalyzedSymbol(currentFragment, resultData));
        }