/*  Description:
                Find the largest license plate in the image
                    - Segment using ThresholdHSVchannels
                    - Remove blobs which are not license plates
            Input:
	            //Original image
	            RGB888Image plateImage	
            Output:
	            //Segmented license plate
	            ref Int16Image binaryPlateImage
            Return:	
	            //License plate found?
	            bool 
         */	
        public static bool FindPlate(RGB888Image plateImage, ref Int16Image binaryPlateImage, TresholdConditions state)
        {
            //Constants
            int c_threshold_h_min = 0;
            int c_threshold_h_max = 0;
            int c_threshold_s_min = 0;
            int c_threshold_s_max = 0;
            int c_threshold_v_min = 0;
            int c_threshold_v_max = 0;
            int c_remove_blobs_min = 0;
            int c_remove_blobs_max = 500;
            
            switch(state)
            {
                case(TresholdConditions.NORMAAL):
                    c_threshold_h_min = 21;
                    c_threshold_h_max = 50;
                    c_threshold_s_min = 100;
                    c_threshold_s_max = 255;
                    c_threshold_v_min = 100;
                    c_threshold_v_max = 255;
                    break;
                case(TresholdConditions.ONDERBELICHT):
                    c_threshold_h_min = 11;
                    c_threshold_h_max = 119;
                    c_threshold_s_min = 23;
                    c_threshold_s_max = 255;
                    c_threshold_v_min = 56;
                    c_threshold_v_max = 176;
                    break;
                case(TresholdConditions.OVERBELICHT):
                    c_threshold_h_min = 0;
                    c_threshold_h_max = 241;
                    c_threshold_s_min = 29;
                    c_threshold_s_max = 241;
                    c_threshold_v_min = 249;
                    c_threshold_v_max = 255;
                    break;
            }

            //*******************************//
            //** Exercise:                 **//
            //**   adjust licenseplate     **//
            //**   segmentation            **//
            //*******************************//            
        
            //Find licenseplate
            HSV888Image plateImageHSV = new HSV888Image();
            //Convert to RGB to HSV
            VisionLab.FastRGBToHSV(plateImage, plateImageHSV);

            //Threshold HSV image
            VisionLab.Threshold3Channels(plateImageHSV, binaryPlateImage, c_threshold_h_min, c_threshold_h_max, c_threshold_s_min, c_threshold_s_max, c_threshold_v_min, c_threshold_v_max);
            
            //Convert to a 32 bit format 
            Int32Image binaryPlateImage32 = new Int32Image();
            VisionLab.Convert(binaryPlateImage, binaryPlateImage32);
           
            //Remove blobs with small areas
            VisionLab.RemoveBlobs(binaryPlateImage32, Connected.EightConnected, BlobAnalyse.BA_Area, c_remove_blobs_min, c_remove_blobs_max);

            //Remove border blobs
            VisionLab.RemoveBorderBlobs(binaryPlateImage32, Connected.EightConnected, Border.AllBorders);

            //Length Breath Ratio
            VisionLab.RemoveBlobs(binaryPlateImage32, Connected.EightConnected, BlobAnalyse.BA_LengthBreadthRatio, 0, 2.5);
            VisionLab.RemoveBlobs(binaryPlateImage32, Connected.EightConnected, BlobAnalyse.BA_LengthBreadthRatio, 6.7, 10);

            // Remove blobs that have to less holes
            VisionLab.RemoveBlobs(binaryPlateImage32, Connected.EightConnected, BlobAnalyse.BA_NrOfHoles, 0, 5);
            // And remove blobs that have a to small area for the holes
            VisionLab.RemoveBlobs(binaryPlateImage32, Connected.EightConnected, BlobAnalyse.BA_AreaHoles, 0, 200);

            //Convert back to a 16 bit format
            VisionLab.Convert(binaryPlateImage32, binaryPlateImage);

            //binPlateImage32.Dispose();
            binaryPlateImage32.Dispose();
            plateImageHSV.Dispose();

            GC.Collect();

            //Return true, if pixels found
            return (VisionLab.SumIntPixels(binaryPlateImage) > 0);
            //return VisionLab.LabelBlobs(binaryPlateImage, Connected.EightConnected) == 1;      
        }
        /*  Description:
         *      Find the largest license plate in the image
         *          - Segment using ThresholdHSVchannels
         *          - Remove blobs which are not license plates
         *  Input:
         *          //Original image
         *          RGB888Image plateImage
         *  Output:
         *          //Segmented license plate
         *          ref Int16Image binaryPlateImage
         *  Return:
         *          //License plate found?
         *          bool
         */
        public static bool FindPlate(RGB888Image plateImage, ref Int16Image binaryPlateImage, TresholdConditions state)
        {
            //Constants
            int c_threshold_h_min  = 0;
            int c_threshold_h_max  = 0;
            int c_threshold_s_min  = 0;
            int c_threshold_s_max  = 0;
            int c_threshold_v_min  = 0;
            int c_threshold_v_max  = 0;
            int c_remove_blobs_min = 0;
            int c_remove_blobs_max = 500;

            switch (state)
            {
            case (TresholdConditions.NORMAAL):
                c_threshold_h_min = 21;
                c_threshold_h_max = 50;
                c_threshold_s_min = 100;
                c_threshold_s_max = 255;
                c_threshold_v_min = 100;
                c_threshold_v_max = 255;
                break;

            case (TresholdConditions.ONDERBELICHT):
                c_threshold_h_min = 11;
                c_threshold_h_max = 119;
                c_threshold_s_min = 23;
                c_threshold_s_max = 255;
                c_threshold_v_min = 56;
                c_threshold_v_max = 176;
                break;

            case (TresholdConditions.OVERBELICHT):
                c_threshold_h_min = 0;
                c_threshold_h_max = 241;
                c_threshold_s_min = 29;
                c_threshold_s_max = 241;
                c_threshold_v_min = 249;
                c_threshold_v_max = 255;
                break;
            }

            //*******************************//
            //** Exercise:                 **//
            //**   adjust licenseplate     **//
            //**   segmentation            **//
            //*******************************//

            //Find licenseplate
            HSV888Image plateImageHSV = new HSV888Image();

            //Convert to RGB to HSV
            VisionLab.FastRGBToHSV(plateImage, plateImageHSV);

            //Threshold HSV image
            VisionLab.Threshold3Channels(plateImageHSV, binaryPlateImage, c_threshold_h_min, c_threshold_h_max, c_threshold_s_min, c_threshold_s_max, c_threshold_v_min, c_threshold_v_max);

            //Convert to a 32 bit format
            Int32Image binaryPlateImage32 = new Int32Image();

            VisionLab.Convert(binaryPlateImage, binaryPlateImage32);

            //Remove blobs with small areas
            VisionLab.RemoveBlobs(binaryPlateImage32, Connected.EightConnected, BlobAnalyse.BA_Area, c_remove_blobs_min, c_remove_blobs_max);

            //Remove border blobs
            VisionLab.RemoveBorderBlobs(binaryPlateImage32, Connected.EightConnected, Border.AllBorders);

            //Length Breath Ratio
            VisionLab.RemoveBlobs(binaryPlateImage32, Connected.EightConnected, BlobAnalyse.BA_LengthBreadthRatio, 0, 2.5);
            VisionLab.RemoveBlobs(binaryPlateImage32, Connected.EightConnected, BlobAnalyse.BA_LengthBreadthRatio, 6.7, 10);

            // Remove blobs that have to less holes
            VisionLab.RemoveBlobs(binaryPlateImage32, Connected.EightConnected, BlobAnalyse.BA_NrOfHoles, 0, 5);
            // And remove blobs that have a to small area for the holes
            VisionLab.RemoveBlobs(binaryPlateImage32, Connected.EightConnected, BlobAnalyse.BA_AreaHoles, 0, 200);

            //Convert back to a 16 bit format
            VisionLab.Convert(binaryPlateImage32, binaryPlateImage);

            //binPlateImage32.Dispose();
            binaryPlateImage32.Dispose();
            plateImageHSV.Dispose();

            GC.Collect();

            //Return true, if pixels found
            return(VisionLab.SumIntPixels(binaryPlateImage) > 0);
            //return VisionLab.LabelBlobs(binaryPlateImage, Connected.EightConnected) == 1;
        }