/// <summary> /// Create the best match for a license plate /// </summary> /// <param name="matcher">The Blobmatcher used for matching the chars</param> public void CalculateBestMatch(BlobMatcher_Int16 matcher) { // Calculate the positon of the stripes getPos(); // Check if the difference between each is valid if (pos2 - pos1 < 2 || // Check if the pattern is valid !((pos1 == 1 && pos2 == 4) || (pos1 == 2 && (pos2 == 5 || pos2 == 4)) )) { // If not then we are done and can't match the pattern // Else if would result in strange license plates return; } // An array which will hold the expected pattern kenType[] partsNum = createpattern(pos1, pos2); // Check if valid pattern if ((partsNum[0] == kenType.NUMBER && partsNum[1] == kenType.NUMBER) || (partsNum[1] == kenType.NUMBER && partsNum[2] == kenType.NUMBER)) { return; } // Check if we got a full pattern if (!checkFullMatch(partsNum)) { tryFullPattern(ref partsNum); // if not try if we can make it full } // Check the found chars and create the best possible license plate createBestMatch(pos1, pos2, partsNum, matcher); }
private void frmMain_Load(object sender, EventArgs e) { VisionLab.InitVisionLib(); lexicon = null; blobMatcher = null; LoadFiles(); }
private void LoadFiles() { try { ErrorTB.Text = ""; String exePath = Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName); if (blobMatcher == null) { blobMatcher = new BlobMatcher_Int16(); } blobMatcher.ReadFromFile(exePath + "\\lic_fonts.pm"); if (lexicon == null) { lexicon = new ClassLexicon(blobMatcher.GetPatternNamesTab()); } } catch (System.Exception ex) { ErrorTB.Text = ex.Message; } }
private void LoadFiles() { try { ErrorTB.Text = ""; String exePath = Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName); if (blobMatcher == null) blobMatcher = new BlobMatcher_Int16(); blobMatcher.ReadFromFile(exePath + "\\lic_fonts.pm"); if (lexicon == null) lexicon = new ClassLexicon(blobMatcher.GetPatternNamesTab()); } catch (System.Exception ex) { ErrorTB.Text = ex.Message; } }
internal static HandleRef getCPtr(BlobMatcher_Int16 obj) { return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; }
/// <summary> /// A method which creates the best possible match for a license plate /// </summary> /// <param name="pos1">The position of the first stripe</param> /// <param name="pos2">The posisiton of the second stripe</param> /// <param name="partsNum">The kenType array</param> /// <param name="matcher">The BlobMatcher</param> private void createBestMatch(int pos1, int pos2, kenType[] partsNum, BlobMatcher_Int16 matcher) { // ************************************************************** // ** Creates the best match based on: ** // ** - If there should be a number, but char found: ** // ** - Find a number in the results and change it ** // ** - If there should be a number and number found ** // ** - If the next match is a character then we can ** // ** up the confidence a lot ** // ** - If the then following match is a number we ** // ** can up it a little ** // ** ** // ** - This also aplies for chars ** // ************************************************************** // A pointer which points to the partsNum place where we are at int partNumPlace = 0; const double maxError = 0.20; // Go through all the chars for (int i = 0; i < chars.Count; i++) { // Check if we need to up the pointer if (i == pos1 || i == pos2) { partNumPlace += 1; } // If there should be a number found if (partsNum[partNumPlace] == kenType.NUMBER && chars[i].error < maxError) { // If it isn't a number if (!Char.IsNumber(chars[i].character[0])) { // Loop through the results and find a number foreach (PatternMatchResult patrn in chars[i].PatternResults) { // if this is a number if (Char.IsNumber(matcher.PatternName(patrn.id)[0])) { // Change the chars value to this number chars[i] = new LicenseCharacter(matcher.PatternName(patrn.id), -0.04, 41); break; } } // End for loop } // End number expected but not found else if (chars[i].error > 0.11) // If there should be a number and a number was found { // Check if the next match is a char if (!Char.IsNumber(matcher.PatternName(chars[i].PatternResults[1].id)[0])) { // If so we can up the confidence chars[i] = new LicenseCharacter(chars[i].character, -0.02, 41); } // If the then following match is a char else if (!Char.IsNumber(matcher.PatternName(chars[i].PatternResults[2].id)[0])) { // Then we up the confidence a little chars[i] = new LicenseCharacter(chars[i].character, -0.01, chars[i].confidence + 0.1); } } } // Check if we should expect a char and the error value isn't to high else if (partsNum[partNumPlace] == kenType.CHAR && chars[i].error < maxError) { // Char expected but number found if (Char.IsNumber(chars[i].character[0])) { // Loop through the matches foreach (PatternMatchResult patrn in chars[i].PatternResults) { if (!Char.IsNumber(matcher.PatternName(patrn.id)[0])) { // If a char was found change the chars[i] value to it chars[i] = new LicenseCharacter(matcher.PatternName(patrn.id), -0.04, 41); break; } } // End for loop } // If we already have a char else if (chars[i].error > 0.11) { // Check if the second match is a number if (Char.IsNumber(matcher.PatternName(chars[i].PatternResults[1].id)[0])) { // If so we can up the confidence a lot chars[i] = new LicenseCharacter(chars[i].character, -0.02, 41); } // Check if the then following match is a number else if (Char.IsNumber(matcher.PatternName(chars[i].PatternResults[2].id)[0])) { // If so then we can up the confidence a little chars[i] = new LicenseCharacter(chars[i].character, -0.01, chars[i].confidence + 0.1); } } // End char expected and char found } // End char expected } // End loop // Done }
/// <summary> /// A method which creates the best possible match for a license plate /// </summary> /// <param name="pos1">The position of the first stripe</param> /// <param name="pos2">The posisiton of the second stripe</param> /// <param name="partsNum">The kenType array</param> /// <param name="matcher">The BlobMatcher</param> private void createBestMatch(int pos1, int pos2, kenType[] partsNum, BlobMatcher_Int16 matcher) { // ************************************************************** // ** Creates the best match based on: ** // ** - If there should be a number, but char found: ** // ** - Find a number in the results and change it ** // ** - If there should be a number and number found ** // ** - If the next match is a character then we can ** // ** up the confidence a lot ** // ** - If the then following match is a number we ** // ** can up it a little ** // ** ** // ** - This also aplies for chars ** // ************************************************************** // A pointer which points to the partsNum place where we are at int partNumPlace = 0; const double maxError = 0.20; // Go through all the chars for (int i = 0; i < chars.Count; i++) { // Check if we need to up the pointer if (i == pos1 || i == pos2) partNumPlace += 1; // If there should be a number found if (partsNum[partNumPlace] == kenType.NUMBER && chars[i].error < maxError) { // If it isn't a number if (!Char.IsNumber(chars[i].character[0])) { // Loop through the results and find a number foreach (PatternMatchResult patrn in chars[i].PatternResults) { // if this is a number if (Char.IsNumber(matcher.PatternName(patrn.id)[0])) { // Change the chars value to this number chars[i] = new LicenseCharacter(matcher.PatternName(patrn.id), -0.04, 41); break; } } // End for loop } // End number expected but not found else if (chars[i].error > 0.11) // If there should be a number and a number was found { // Check if the next match is a char if (!Char.IsNumber(matcher.PatternName(chars[i].PatternResults[1].id)[0])) { // If so we can up the confidence chars[i] = new LicenseCharacter(chars[i].character, -0.02, 41); } // If the then following match is a char else if (!Char.IsNumber(matcher.PatternName(chars[i].PatternResults[2].id)[0])) { // Then we up the confidence a little chars[i] = new LicenseCharacter(chars[i].character, -0.01, chars[i].confidence + 0.1); } } } // Check if we should expect a char and the error value isn't to high else if (partsNum[partNumPlace] == kenType.CHAR && chars[i].error < maxError) { // Char expected but number found if (Char.IsNumber(chars[i].character[0])) { // Loop through the matches foreach (PatternMatchResult patrn in chars[i].PatternResults) { if (!Char.IsNumber(matcher.PatternName(patrn.id)[0])) { // If a char was found change the chars[i] value to it chars[i] = new LicenseCharacter(matcher.PatternName(patrn.id), -0.04, 41); break; } } // End for loop } // If we already have a char else if (chars[i].error > 0.11) { // Check if the second match is a number if (Char.IsNumber(matcher.PatternName(chars[i].PatternResults[1].id)[0])) { // If so we can up the confidence a lot chars[i] = new LicenseCharacter(chars[i].character, -0.02, 41); } // Check if the then following match is a number else if (Char.IsNumber(matcher.PatternName(chars[i].PatternResults[2].id)[0])) { // If so then we can up the confidence a little chars[i] = new LicenseCharacter(chars[i].character, -0.01, chars[i].confidence + 0.1); } } // End char expected and char found } // End char expected } // End loop // Done }
/// <summary> /// Create the best match for a license plate /// </summary> /// <param name="matcher">The Blobmatcher used for matching the chars</param> public void CalculateBestMatch(BlobMatcher_Int16 matcher) { // Calculate the positon of the stripes getPos(); // Check if the difference between each is valid if (pos2 - pos1 < 2 || // Check if the pattern is valid !((pos1 == 1 && pos2 == 4) || (pos1 == 2 && (pos2 == 5 || pos2 == 4)) )) // If not then we are done and can't match the pattern // Else if would result in strange license plates return; // An array which will hold the expected pattern kenType[] partsNum = createpattern(pos1, pos2); // Check if valid pattern if ((partsNum[0] == kenType.NUMBER && partsNum[1] == kenType.NUMBER) || (partsNum[1] == kenType.NUMBER && partsNum[2] == kenType.NUMBER)) return; // Check if we got a full pattern if (!checkFullMatch(partsNum)) tryFullPattern(ref partsNum); // if not try if we can make it full // Check the found chars and create the best possible license plate createBestMatch(pos1, pos2, partsNum, matcher); }
/* * Description: * Read the license plate * Input: * //Rectified license plate image containing six characters * Int32Image labeledRectifiedPlateImage * BlobMatcher_Int16 matcher //initialized blobmatcher * ClassLexicon lexicon //initialized lexicon * Output: * //Result by the blob matcher * ref LicensePlate result * //Result by the lexicon * ref LicensePlate lexiconResult * Return: * //six characters found * bool */ public static bool MatchPlate(Int32Image binaryCharacterImage, BlobMatcher_Int16 matcher, ClassLexicon lexicon, ref LicensePlate result, ref LicensePlate lexiconResult) { //Check if 6 characters/blobs have been found and label image. if (VisionLab.LabelBlobs(binaryCharacterImage, Connected.EightConnected) != 6) { return(false); } //Calculate dimensions and locations of all characters/blobs. vector_BlobAnalyse ba_vec = new vector_BlobAnalyse(); ba_vec.Add(BlobAnalyse.BA_TopLeft); ba_vec.Add(BlobAnalyse.BA_Height); ba_vec.Add(BlobAnalyse.BA_Width); vector_Blob returnBlobs = new vector_Blob(); VisionLab.BlobAnalysis(binaryCharacterImage, VisionLab.VectorToSet_BlobAnalyse(ba_vec), VisionLab.MaxPixel(binaryCharacterImage), returnBlobs, SortOrder.SortDown, BlobAnalyse.BA_TopLeft, UseXOrY.UseX); ba_vec.Dispose(); Int32Image binaryCharacter = new Int32Image(); Int16Image binaryCharacter16 = new Int16Image(); //Create data structure for lexicon. vector_vector_LetterMatch match = new vector_vector_LetterMatch(); //Process each character/blob. foreach (Blob b in returnBlobs) { //Cut out character VisionLab.ROI(binaryCharacterImage, binaryCharacter, b.TopLeft(), new HeightWidth(b.Height(), b.Width())); //Convert ROI result to binary VisionLab.ClipPixelValue(binaryCharacter, 0, 1); //Calculate character's classification for all classes. vector_PatternMatchResult returnMatches = new vector_PatternMatchResult(); VisionLab.Convert(binaryCharacter, binaryCharacter16); float conf = matcher.AllMatches(binaryCharacter16, (float)-0.5, (float)0.5, returnMatches); float err = returnMatches[0].error; int id = returnMatches[0].id; string chr = matcher.PatternName(id); //Fill datastructure for lexicon. match.Add(VisionLabEx.PatternMatchResultToLetterMatch(returnMatches)); //Store best match in result result.characters.Add(new LicenseCharacter(chr, err, conf)); } //Validate match with lexicon. vector_int bestWord = new vector_int(); lexiconResult.confidence = lexicon.FindBestWord(match, bestWord, Optimize.OptimizeForMinimum); for (int i = 0; i < bestWord.Count; i++) { string character = matcher.PatternName(bestWord[i]); //Store lexicon result lexiconResult.characters.Add(new LicenseCharacter(character)); } binaryCharacter.Dispose(); binaryCharacter16.Dispose(); returnBlobs.Dispose(); match.Dispose(); bestWord.Dispose(); //GC.Collect(); return(true); }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(BlobMatcher_Int16 obj) { return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }
internal static HandleRef getCPtr(BlobMatcher_Int16 obj) { return((obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr); }
/* Description: Read the license plate Input: //Rectified license plate image containing six characters Int16Image labeledRectifiedPlateImage BlobMatcher_Int16 matcher //initialized blobmatcher ClassLexicon lexicon //initialized lexicon Output: //Result by the blob matcher ref LicensePlate result //Result by the lexicon ref LicensePlate lexiconResult Return: //six characters found bool */ public static bool MatchPlate(Int16Image binaryCharacterImage, BlobMatcher_Int16 matcher, ClassLexicon lexicon, ref LicensePlate result, ref LicensePlate lexiconResult, bool dilate) { // NIEUW // 2de optie voor aanroep als eerste low confidence levert if (dilate) { Int16Image temp = new Int16Image(); VisionLab.Dilation(binaryCharacterImage, temp, new Mask_Int32(3, 3, 1)); binaryCharacterImage = new Int16Image(temp); temp.Dispose(); } if (VisionLab.LabelBlobs(binaryCharacterImage, Connected.EightConnected) != 6) return false; //Calculate dimensions and locations of all characters/blobs. vector_BlobAnalyse ba_vec = new vector_BlobAnalyse(); ba_vec.Add(BlobAnalyse.BA_TopLeft); ba_vec.Add(BlobAnalyse.BA_Height); ba_vec.Add(BlobAnalyse.BA_Width); vector_Blob returnBlobs = new vector_Blob(); VisionLab.BlobAnalysis(binaryCharacterImage, VisionLab.VectorToSet_BlobAnalyse(ba_vec), VisionLab.MaxPixel(binaryCharacterImage), returnBlobs, SortOrder.SortDown, BlobAnalyse.BA_TopLeft, UseXOrY.UseX); ba_vec.Dispose(); Int16Image binaryCharacter = new Int16Image(); //Create data structure for lexicon. vector_vector_LetterMatch match = new vector_vector_LetterMatch(); // NIEUW // Change the matcher params matcher.ChangeParams(60, 10, 64, 0); //Process each character/blob. foreach (Blob b in returnBlobs) { //Cut out character VisionLab.ROI(binaryCharacterImage, binaryCharacter, b.TopLeft(), new HeightWidth(b.Height(), b.Width())); //Convert ROI result to binary VisionLab.ClipPixelValue(binaryCharacter, 0, 1); //Calculate character's classification for all classes. vector_PatternMatchResult returnMatches = new vector_PatternMatchResult(); float conf = matcher.AllMatches(binaryCharacter, (float)-0.5, (float)0.5, returnMatches); float err = returnMatches[0].error; int id = returnMatches[0].id; string chr = matcher.PatternName(id); // NIEUW // If error to big decrease the confidence if(err > 0.20f) conf -= 0.2f; //Fill datastructure for lexicon. match.Add(VisionLabEx.PatternMatchResultToLetterMatch(returnMatches)); //Store best match in result result.characters.Add( new LicenseCharacter( chr, err, conf, // NIEUW // Extra param: The middle of a character // (used for matching patterns) b.TopLeft().x + ((b.TopRight().x - b.TopLeft().x)/2) , // NIEUW // All other results that we're found // So we can switch between em returnMatches )); } //Validate match with lexicon. vector_int bestWord = new vector_int(); lexiconResult.confidence = lexicon.FindBestWord(match, bestWord, Optimize.OptimizeForMinimum); for (int i = 0; i < bestWord.Count; i++) { string character = matcher.PatternName(bestWord[i]); //Store lexicon result lexiconResult.characters.Add(new LicenseCharacter(character)); } // NIEUW // Create the best match with the aid of the pattern matcher result.CalculateBestMatch(matcher); binaryCharacter.Dispose(); returnBlobs.Dispose(); match.Dispose(); bestWord.Dispose(); GC.Collect(); return true; }
/* * Description: * Read the license plate * Input: * //Rectified license plate image containing six characters * Int16Image labeledRectifiedPlateImage * BlobMatcher_Int16 matcher //initialized blobmatcher * ClassLexicon lexicon //initialized lexicon * Output: * //Result by the blob matcher * ref LicensePlate result * //Result by the lexicon * ref LicensePlate lexiconResult * Return: * //six characters found * bool */ public static bool MatchPlate(Int16Image binaryCharacterImage, BlobMatcher_Int16 matcher, ClassLexicon lexicon, ref LicensePlate result, ref LicensePlate lexiconResult, bool dilate) { // NIEUW // 2de optie voor aanroep als eerste low confidence levert if (dilate) { Int16Image temp = new Int16Image(); VisionLab.Dilation(binaryCharacterImage, temp, new Mask_Int32(3, 3, 1)); binaryCharacterImage = new Int16Image(temp); temp.Dispose(); } if (VisionLab.LabelBlobs(binaryCharacterImage, Connected.EightConnected) != 6) { return(false); } //Calculate dimensions and locations of all characters/blobs. vector_BlobAnalyse ba_vec = new vector_BlobAnalyse(); ba_vec.Add(BlobAnalyse.BA_TopLeft); ba_vec.Add(BlobAnalyse.BA_Height); ba_vec.Add(BlobAnalyse.BA_Width); vector_Blob returnBlobs = new vector_Blob(); VisionLab.BlobAnalysis(binaryCharacterImage, VisionLab.VectorToSet_BlobAnalyse(ba_vec), VisionLab.MaxPixel(binaryCharacterImage), returnBlobs, SortOrder.SortDown, BlobAnalyse.BA_TopLeft, UseXOrY.UseX); ba_vec.Dispose(); Int16Image binaryCharacter = new Int16Image(); //Create data structure for lexicon. vector_vector_LetterMatch match = new vector_vector_LetterMatch(); // NIEUW // Change the matcher params matcher.ChangeParams(60, 10, 64, 0); //Process each character/blob. foreach (Blob b in returnBlobs) { //Cut out character VisionLab.ROI(binaryCharacterImage, binaryCharacter, b.TopLeft(), new HeightWidth(b.Height(), b.Width())); //Convert ROI result to binary VisionLab.ClipPixelValue(binaryCharacter, 0, 1); //Calculate character's classification for all classes. vector_PatternMatchResult returnMatches = new vector_PatternMatchResult(); float conf = matcher.AllMatches(binaryCharacter, (float)-0.5, (float)0.5, returnMatches); float err = returnMatches[0].error; int id = returnMatches[0].id; string chr = matcher.PatternName(id); // NIEUW // If error to big decrease the confidence if (err > 0.20f) { conf -= 0.2f; } //Fill datastructure for lexicon. match.Add(VisionLabEx.PatternMatchResultToLetterMatch(returnMatches)); //Store best match in result result.characters.Add( new LicenseCharacter( chr, err, conf, // NIEUW // Extra param: The middle of a character // (used for matching patterns) b.TopLeft().x + ((b.TopRight().x - b.TopLeft().x) / 2), // NIEUW // All other results that we're found // So we can switch between em returnMatches )); } //Validate match with lexicon. vector_int bestWord = new vector_int(); lexiconResult.confidence = lexicon.FindBestWord(match, bestWord, Optimize.OptimizeForMinimum); for (int i = 0; i < bestWord.Count; i++) { string character = matcher.PatternName(bestWord[i]); //Store lexicon result lexiconResult.characters.Add(new LicenseCharacter(character)); } // NIEUW // Create the best match with the aid of the pattern matcher result.CalculateBestMatch(matcher); binaryCharacter.Dispose(); returnBlobs.Dispose(); match.Dispose(); bestWord.Dispose(); GC.Collect(); return(true); }