/// <summary>
        ///
        /// </summary>
        /// <param name="sym"></param>
        /// <param name="image">Used to display the context when entering a character.</param>
        /// <param name="tolerance"></param>
        /// <param name="onlyNumbers"></param>
        /// <returns></returns>
        public string FindMatchingChar(RecognizedCharData sym, bool[,] image, float tolerance = 0.3f, bool onlyNumbers = false)
        {
            var recognizedPattern = new Pattern(sym.Pattern, sym.YOffset);

            //// debug
            //Boolean2DimArrayConverter.ToDebugLog(recognizedPattern.Data);
            //var letterWasSortedOutByAperture = false;

            //string aperturesString = string.Empty;
            //for (int i = 0; i < 8; i++)
            //{
            //    if (i % 2 == 0)
            //        aperturesString += "|";
            //    aperturesString += ((recognizedPattern.Apertures >> i) & 1) == 1 ? "▬" : " ";
            //}
            //Debug.WriteLine($"Apertures: {aperturesString}");


            var widthRecognized            = recognizedPattern.Width;
            var heightRecognized           = recognizedPattern.Height;
            var recognizedHeightWithOffset = heightRecognized + sym.Coords.Y;

            float  bestMatchDifference = float.MaxValue;
            string bestMatch           = null;
            int    maxAllowedSet       = (int)(recognizedPattern.SetPixels * (1 + tolerance)) + 1;
            int    minAllowedSet       = (int)(recognizedPattern.SetPixels * (1 - tolerance));

            foreach (var c in Texts)
            {
                // if only numbers are expected, skip non numerical patterns
                if (onlyNumbers && !OnlyNumbersChars.Contains(c.Text))
                {
                    continue;
                }

                foreach (var pattern in c.Patterns)
                {
                    if (HammingWeight.SetBitCount((byte)(pattern.Apertures ^ recognizedPattern.Apertures)) > 1 ||
                        Math.Abs(pattern.YOffset - recognizedPattern.YOffset) > 3
                        )
                    {
                        continue;
                    }

                    //var currentLetterWasSortedOutByAperture = pattern.Apertures != recognizedPattern.Apertures;

                    int minWidth  = Math.Min(pattern.Width, widthRecognized);
                    int maxWidth  = Math.Max(pattern.Width, widthRecognized);
                    var widthDiff = maxWidth - minWidth;
                    if (pattern.SetPixels > maxAllowedSet ||
                        pattern.SetPixels < minAllowedSet ||
                        (widthDiff > 2 && widthDiff > maxWidth * 0.2))
                    {
                        continue;                                                   // if dimensions is too different ignore pattern
                    }
                    int minHeight  = Math.Min(pattern.Height, heightRecognized);
                    int maxHeight  = Math.Max(pattern.Height, heightRecognized);
                    var heightDiff = maxHeight - minHeight;
                    if (heightDiff > 2 && heightDiff > maxHeight * 0.2)
                    {
                        continue;
                    }

                    var allowedDifference = pattern.SetPixels * 2 * tolerance;

                    // Attempted to do offset shifting here but got too many false recognitions here, might need some tweaking.
                    //var minOffsetX = xSizeFound > 2 ? -1 : 0;
                    //var maxOffsetX = xSizeFound > 2 ? 1 : 0;
                    //var minOffsetY = xSizeFound > 2 ? -1 : 0;
                    //var maxOffsetY = xSizeFound > 2 ? 1 : 0;

                    //for (var offSetX = minOffsetX; offSetX <= maxOffsetX; offSetX++)
                    //{
                    //    for (var offSetY = minOffsetY; offSetY <= maxOffsetY; offSetY++)
                    //    {
                    var dif  = 0f;
                    var fail = false;

                    // y offset. Small character at the baseline like dots have mostly empty pixels.
                    var yStart = Math.Min(sym.Coords.Y, pattern.YOffset);
                    var patternHeightWithOffset = pattern.Height + pattern.YOffset;

                    Pattern overlappingPattern; // the pattern that is more than 1 px larger than the other. testing that margin is simpler.
                    int     widthTesting;
                    if (widthRecognized > pattern.Width)
                    {
                        widthTesting       = widthRecognized;
                        overlappingPattern = recognizedPattern;
                    }
                    else
                    {
                        widthTesting       = pattern.Width;
                        overlappingPattern = pattern;
                    }
                    var widthMinPlusOne = Math.Min(widthRecognized, pattern.Width) + 1;

                    // pixels too far outside of the narrower pattern never have a match or a possible neighbor in the other one, they can be sorted out fast
                    if (widthTesting - widthMinPlusOne > 0)
                    {
                        for (int y = 0; !fail && y < overlappingPattern.Height; y++)
                        {
                            for (var x = widthMinPlusOne; x < widthTesting; x++)
                            {
                                if (overlappingPattern[x, y])
                                {
                                    dif += 1;
                                    if (dif > allowedDifference)
                                    {
                                        fail = true;
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    for (var y = yStart; !fail && y < recognizedHeightWithOffset && y < patternHeightWithOffset; y++)
                    {
                        //var curPatternY = y;// + offSetY;
                        var patternYIndex    = y - pattern.YOffset;
                        var recognizedYIndex = y - sym.Coords.Y;

                        for (var x = 0; x < widthMinPlusOne; x++)
                        {
                            //var curPatternX = x;// + offSetX;
                            //if (curPatternX < 0 || curPatternY < 0) continue;
                            //if (y >= heightRecognized || x >= widthRecognized) continue;

                            var cHave = recognizedYIndex >= 0 && x < widthRecognized && recognizedPattern[x, recognizedYIndex];
                            var pHave = patternYIndex >= 0 && x < pattern.Width && pattern[x, patternYIndex];

                            // if the bits are different, check if the total number of different bits is too large for a match and if to ignore this pattern
                            if (cHave != pHave)
                            {
                                // tolerance of difference if a nearby bit is equal
                                dif += IsNearby(cHave ? pattern.Data : recognizedPattern.Data, x, cHave ? patternYIndex : recognizedYIndex) ? 0.4f : 1f;
                                if (dif > allowedDifference)
                                {
                                    fail = true;
                                    break;
                                }
                            }
                        }
                    }

                    if (!fail && bestMatchDifference > dif)
                    {
                        if (dif == 0)
                        {
                            //Debug.WriteLine($"matched with {c.Text} (dif: {dif})");
                            //if (currentLetterWasSortedOutByAperture)
                            //    Debug.WriteLine("Would have been sorted out by Aperture");
                            return(c.Text); // there is no better match
                        }


                        //letterWasSortedOutByAperture = currentLetterWasSortedOutByAperture;
                        bestMatchDifference = dif;
                        bestMatch           = c.Text;
                    }
                    //    }
                    //}
                }
            }

            if (!string.IsNullOrEmpty(bestMatch))
            {
                //Debug.WriteLine($"matched with {bestMatch} (dif: {bestMatchDifference})");
                //if (letterWasSortedOutByAperture)
                //    Debug.WriteLine("Would have been sorted out by Aperture");
                return(bestMatch);
            }


            // no match was found

            if (!TrainingSettings.IsTrainingEnabled)
            {
                return("�"); //string.Empty;
            }

            var manualChar = new RecognitionTrainingForm(sym, image).Prompt();

            if (string.IsNullOrEmpty(manualChar))
            {
                return(manualChar);
            }

            return(AddNewPattern(recognizedPattern, manualChar));
        }
Exemplo n.º 2
0
 /// <inheritdoc />
 public float Similarity(ImageDifferenceHash64 otherHash)
 {
     return(HammingWeight.CalculateSimilarity(InternalValue, otherHash.InternalValue));
 }
Exemplo n.º 3
0
 /// <inheritdoc />
 public float Similarity(ImageAverageHash otherHash)
 {
     return(HammingWeight.CalculateSimilarity(InternalValue, otherHash.InternalValue));
 }
Exemplo n.º 4
0
        static void Main(string[] args)
        {
            Mine mine = new Mine();

            int[][] twoD = new int[2][];
            twoD[0] = new int[] { 0, 0 };
            twoD[1] = new int[] { 0, 1 };


            int[,] field = mine.Minesweeper(twoD, 3, 4);

            int mRow = field.GetUpperBound(0);
            int mCol = field.GetUpperBound(1);

            for (int r = 0; r <= mRow; r++)
            {
                for (int c = 0; c <= mCol; c++)
                {
                    Console.Write(field[r, c] + " ");
                }
                Console.WriteLine("");
            }

            int[]        bst          = { 2, 3, 4, 10, 40 };
            BinarySearch binarySearch = new BinarySearch();
            int          n            = bst.Length;
            int          x            = 10;

            Console.WriteLine("Recurcive: The index is " + binarySearch.BinarySearchRecursive(bst, 0, n - 1, x));
            Console.WriteLine("Itirative: The index is " + binarySearch.BinarySearchItirative(bst, x));


            var path = new List <int>();
            var Prev = new Dictionary <int, int>();

            Console.WriteLine(string.Join(", ", search.DFS(unDirectedgraph, 1)));
            Console.WriteLine(string.Join(", ", search.BFS(unDirectedgraph, 1, ref Prev, v => path.Add(v))));
            Console.WriteLine("Trace Path...");
            Console.WriteLine(string.Join(", ", path));
            foreach (var vertex in vertices)
            {
                Console.WriteLine("shortest path to {0,2}: {1}", vertex, string.Join(", ", search.ShortestPathFromPrev(Prev, 1, vertex)));
            }
            Console.WriteLine("Topological Sort....");
            Console.WriteLine(string.Join(", ", TopSort()));
            Console.WriteLine("Is 'create' anagram of 'eaterc'? : " + anagram.isAnagram("create", "eaterc"));

            void checkPalindrome(string str)
            {
                Palindrome p = new Palindrome();

                Console.WriteLine("Is this word a palindrome? " + str);
                Console.WriteLine(p.isPalidrome(str, false));
            };

            checkPalindrome("hello");
            checkPalindrome("motor");
            checkPalindrome("rotor");

            Misc misc = new Misc();

            int[] arr1 = { 5, 6, 1, 2, 3, 4 };
            int   n1   = arr1.Length;

            Console.WriteLine("The minimum element is " +
                              misc.FindMinInSortedRotated(arr1, 0, n1 - 1));

            int[] arr2 = { 1, 2, 3, 4 };
            int   n2   = arr2.Length;

            Console.WriteLine("The minimum element is " +
                              misc.FindMinInSortedRotated(arr2, 0, n2 - 1));

            int[] arr3 = { 1 };
            int   n3   = arr3.Length;

            Console.WriteLine("The minimum element is " +
                              misc.FindMinInSortedRotated(arr3, 0, n3 - 1));

            int[] arr4 = { 1, 2 };
            int   n4   = arr4.Length;

            Console.WriteLine("The minimum element is " +
                              misc.FindMinInSortedRotated(arr4, 0, n4 - 1));

            int[] arr5 = { 2, 1 };
            int   n5   = arr5.Length;

            Console.WriteLine("The minimum element is " +
                              misc.FindMinInSortedRotated(arr5, 0, n5 - 1));

            int[] arr6 = { 5, 6, 7, 1, 2, 3, 4 };
            int   n6   = arr6.Length;

            Console.WriteLine("The minimum element is " +
                              misc.FindMinInSortedRotated(arr6, 0, n1 - 1));

            int[] arr7 = { 1, 2, 3, 4, 5, 6, 7 };
            int   n7   = arr7.Length;

            Console.WriteLine("The minimum element is " +
                              misc.FindMinInSortedRotated(arr7, 0, n7 - 1));

            int[] arr8 = { 2, 3, 4, 5, 6, 7, 8, 1 };
            int   n8   = arr8.Length;

            Console.WriteLine("The minimum element is " +
                              misc.FindMinInSortedRotated(arr8, 0, n8 - 1));

            int[] arr9 = { 3, 4, 5, 1, 2 };
            int   n9   = arr9.Length;

            Console.WriteLine("The minimum element is " +
                              misc.FindMinInSortedRotated(arr9, 0, n9 - 1));

            int[]      arr   = { 64, 34, 25, 12, 22, 11, 90 };
            BubbleSort bSort = new BubbleSort();

            bSort.Sort(arr);
            Console.Write("arr = { 64, 34, 25, 12, 22, 11, 90 } => Sorted array = ");
            printArray(arr);

            int[]     ar = { 99, 44, 6, 2, 1, 5, 63, 87, 283, 4, 0 };
            QuickSort qs = new QuickSort();

            qs.Quick_Sort(ar);
            Console.Write("arr = { 99, 44, 6, 2, 1, 5, 63, 87, 283, 4, 0} => Insertion Sorted array = ");
            printArray(ar);

            int[]         arr_1 = { 64, 34, 25, 12, 22, 11, 90 };
            SelectionSort sSort = new SelectionSort();

            sSort.Sort(arr_1);
            Console.Write("arr_1 = { 64, 34, 25, 12, 22, 11, 90 } => Sorted array = ");
            printArray(arr_1);

            WordLadder wordLadder = new WordLadder();
            string     strpath    = "";
            int        i          = wordLadder.LadderLength("hit", "cog", ref strpath);

            Console.WriteLine(strpath);

            HammingWeight hw = new HammingWeight();

            int[] hw_1 = { 31, 51 };
            Console.WriteLine("Hamming Weight of hw_1 = {    31,51} = " + hw.GetHammingWeightbyPreprocessing(hw_1));

            Fibonacci fib = new Fibonacci();

            Console.WriteLine("6th Fibonacci number by rec is : " + fib.FibRecursive(6));
            Console.WriteLine("6th Fibonacci number by DP is : " + fib.FibDP(6));
            Console.WriteLine("6th Fibonacci number by Bottomup is : " + fib.FibBottomUp(6));

            Subsets subsets = new Subsets();

            int[] arrSS = new int[] { 2, 4, 6, 10 };
            Console.WriteLine("No. of subsets whose sum is 16 in { 2, 4, 6, 10 } : " + subsets.CountSubsetsDP(arrSS, 16));

            HasPairWithSum obj = new HasPairWithSum();

            Console.WriteLine("Does the array { 2, 4, 6, 10 } has a pair whose sum is 12: " + obj.isPairWithSumExists(arrSS, 12));

            MergeArrays ma = new MergeArrays();

            int[] arrSorted2 = new int[] { 0, 3, 4 };
            int[] arrSorted1 = new int[] { 2, 4, 6, 10 };

            Console.WriteLine("Merged Sorted array for the sorted arrays { 0, 3, 4} and { 2, 4, 6, 10 } : ");
            printArray(ma.MergeSortedArrays(arrSorted1, arrSorted2));

            MoveZeros mz = new MoveZeros();

            Console.WriteLine("Move Zeros from {0,0,1} ");
            int[] mzA = new int[] { 0, 0, 1 };
            mz.MoveZeroes(mzA);
            printArray(mzA);

            FirstRecurring fr = new FirstRecurring();

            int[] fra = new int[] { 2, 5, 1, 2, 3, 5, 1, 2, 4 };
            Console.WriteLine("First recurring element in  { 2, 5, 1, 2, 3, 5, 1, 2, 4 } is: " + fr.GetFirstRecurringElement <int>(fra));

            Islands il = new Islands();

            int[,] M = new int[, ] {
                { 1, 1, 0, 0, 0 },
                { 0, 1, 0, 0, 1 },
                { 1, 0, 0, 1, 1 },
                { 0, 0, 0, 0, 0 },
                { 1, 0, 1, 0, 1 }
            };
            Console.Write("Number of islands is: " +
                          il.countIslands(M));

            LongestPalindromicSubstring lss = new LongestPalindromicSubstring();

            Console.Write("LongestPalindrome in 'babad' : " + lss.LongestPalindrome("cbbd"));


            BinaryTree tree = new BinaryTree();

            tree.root            = new TreeNode(1);
            tree.root.left       = new TreeNode(2);
            tree.root.right      = new TreeNode(3);
            tree.root.left.left  = new TreeNode(4);
            tree.root.left.right = new TreeNode(5);
            Console.WriteLine("");
            Traversals trav = new Traversals();

            trav.printInorder(tree.root);
            Console.WriteLine("");
            trav.printPreorder(tree.root);
            Console.WriteLine("");
            trav.printPostOrder(tree.root);
            Console.WriteLine("");

            Console.Write("The height of the tree is : " + trav.GetTreeHeight(tree.root));
            Console.WriteLine("Level Order:");
            trav.LevelOrderTraversal(tree.root);
        }