/// <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)); }
/// <inheritdoc /> public float Similarity(ImageDifferenceHash64 otherHash) { return(HammingWeight.CalculateSimilarity(InternalValue, otherHash.InternalValue)); }
/// <inheritdoc /> public float Similarity(ImageAverageHash otherHash) { return(HammingWeight.CalculateSimilarity(InternalValue, otherHash.InternalValue)); }
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); }