/// <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);
        }
Пример #2
0
 private void frmMain_Load(object sender, EventArgs e)
 {
     VisionLab.InitVisionLib();
     lexicon     = null;
     blobMatcher = null;
     LoadFiles();
 }
Пример #3
0
        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;
            }
        }
Пример #4
0
        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;
            }
        }
Пример #5
0
 private void frmMain_Load(object sender, EventArgs e)
 {
     VisionLab.InitVisionLib();
     lexicon = null;
     blobMatcher = null;
     LoadFiles();
 }
 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);
        }
Пример #10
0
        /*
         *  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);
        }