/*
         *  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);
        }