예제 #1
0
        //自动样品分割
        public static List <CharInfo> SplitePlateForAutoSample(Mat plateMat)
        {
            List <CharInfo> result = new List <CharInfo>();
            List <CharInfo> charInfos_Original_Blue       = SplitePlateByOriginal(plateMat, plateMat, PlateColor.蓝牌);
            List <CharInfo> charInfos_IndexTransform_Blue = SplitePlateByIndexTransform(plateMat,
                                                                                        PlateColor.蓝牌);
            List <CharInfo> charInfos_GammaTransform_Blue = SplitePlateByGammaTransform(plateMat,
                                                                                        PlateColor.蓝牌);
            List <CharInfo> charInfos_LogTransform_Blue = SplitePlateByLogTransform(plateMat, PlateColor.蓝牌);
            List <CharInfo> charInfos_Blue = new List <CharInfo>();

            charInfos_Blue.AddRange(charInfos_Original_Blue.ToArray());
            charInfos_Blue.AddRange(charInfos_IndexTransform_Blue.ToArray());
            charInfos_Blue.AddRange(charInfos_GammaTransform_Blue.ToArray());
            charInfos_Blue.AddRange(charInfos_LogTransform_Blue.ToArray());
            int isCharCount = 0;

            for (int index = 0; index < charInfos_Blue.Count; index++)
            {
                CharInfo charInfo = charInfos_Blue[index];
                charInfo.PlateChar = PlateChar_SVM.Test(charInfo.OriginalMat);
                if (charInfo.PlateChar != PlateChar.非字符)
                {
                    isCharCount++;
                }
            }
            if (isCharCount >= 15)
            {
                return(charInfos_Blue);
            }
            //如果用蓝色切分字符,少于15个,就再用黄色尝试切分
            List <CharInfo> charInfos_Original_Yellow       = SplitePlateByOriginal(plateMat, plateMat, PlateColor.黄牌);
            List <CharInfo> charInfos_IndexTransform_Yellow = SplitePlateByIndexTransform(plateMat,
                                                                                          PlateColor.黄牌);
            List <CharInfo> charInfos_GammaTransform_Yellow = SplitePlateByGammaTransform(plateMat,
                                                                                          PlateColor.黄牌);
            List <CharInfo> charInfos_LogTransform_Yellow = SplitePlateByLogTransform(plateMat,
                                                                                      PlateColor.黄牌);
            List <CharInfo> charInfos_Yellow = new List <CharInfo>();

            charInfos_Yellow.AddRange(charInfos_Original_Yellow.ToArray());
            charInfos_Yellow.AddRange(charInfos_IndexTransform_Yellow.ToArray());
            charInfos_Yellow.AddRange(charInfos_GammaTransform_Yellow.ToArray());
            charInfos_Yellow.AddRange(charInfos_LogTransform_Yellow.ToArray());
            isCharCount = 0;
            for (int index = 0; index < charInfos_Yellow.Count; index++)
            {
                CharInfo charInfo = charInfos_Yellow[index];
                charInfo.PlateChar = PlateChar_SVM.Test(charInfo.OriginalMat);
                if (charInfo.PlateChar != PlateChar.非字符)
                {
                    isCharCount++;
                }
            }
            if (isCharCount >= 15)
            {
                return(charInfos_Yellow);
            }
            return(new List <CharInfo>()); //返回?长度为零的集合
        }
예제 #2
0
        public static Mat GetCharSvmHOGFeatures(Mat img)
        {
            float[] descriptor = PlateChar_SVM.ComputeHogDescriptors(img);
            Mat     feature    = Float2Mat(descriptor);

            return(feature);
        }
예제 #3
0
        //
        public static PlateInfo GetPlateInfo(PlateInfo plateInfo, PlateColor plateColor, CharSplitMethod
                                             splitMethod)
        {
            PlateInfo result = new PlateInfo();

            result.PlateCategory     = plateInfo.PlateCategory;
            result.OriginalMat       = plateInfo.OriginalMat;
            result.OriginalRect      = plateInfo.OriginalRect;
            result.PlateLocateMethod = plateInfo.PlateLocateMethod;
            result.PlateColor        = plateColor;
            List <CharInfo> charInfos = new List <CharInfo>();

            switch (splitMethod)
            {
            case CharSplitMethod.伽马:
                charInfos = CharSegment_V3.SplitePlateByGammaTransform(plateInfo.OriginalMat,
                                                                       plateColor);
                break;

            case CharSplitMethod.指数:
                charInfos = CharSegment_V3.SplitePlateByIndexTransform(plateInfo.OriginalMat, plateColor);
                break;

            case CharSplitMethod.对数:
                charInfos = CharSegment_V3.SplitePlateByLogTransform(plateInfo.OriginalMat, plateColor);
                break;

            case CharSplitMethod.原图:
            default:
                charInfos = CharSegment_V3.SplitePlateByOriginal(plateInfo.OriginalMat,
                                                                 plateInfo.OriginalMat, plateColor);
                break;
            }
            //启动SVM识别字符并将其中的非字符去除
            for (int index = charInfos.Count - 1; index >= 0; index--)
            {
                CharInfo  charInfo  = charInfos[index];
                PlateChar plateChar = PlateChar_SVM.Test(charInfo.OriginalMat);
                if (plateChar == PlateChar.非字符)
                {
                    charInfos.RemoveAt(index);
                }
                charInfo.PlateChar = plateChar;
            }
            result.CharInfos = charInfos;
            //检测
            CheckLeftAndRightToRemove(result);
            CheckPlateColor(result);
            return(result);
        }
예제 #4
0
        //对分割好的字符进行识别,并得到字符数组
        public static List <CharInfo> SpliteCharsInPlateMat(Mat plateMat, List <Rect> rects)
        {
            if (PlateChar_SVM.IsReady == false)
            {
                throw new Exception("字符识别库没有准备好");
            }
            List <CharInfo> result = new List <CharInfo>();

            for (int index = 0; index < rects.Count; index++)
            {
                Rect rect = rects[index];
                rect = Utilities.GetSafeRect(rect, plateMat);
                CharInfo charInfo    = new CharInfo();
                Mat      originalMat = plateMat.SubMat(rect);
                charInfo.OriginalMat  = originalMat;
                charInfo.OriginalRect = rect;

                charInfo.PlateChar = PlateChar_SVM.Test(originalMat);
                result.Add(charInfo);
            }
            result.Sort(new CharInfoLeftComparer());
            return(result);
        }
예제 #5
0
        //对字符进行训练
        public static void TrainSVMDataForCharRecog(string path)
        {
            Console.WriteLine("preparing for training data!!!!");
            List <TrainStruct>    svmData  = new List <TrainStruct>();
            List <List <string> > ImgFiles = new List <List <string> >();

            //for(int index=0;index<10;index++)
            //{
            //    string label = "_" + index.ToString();
            //    string filePath = @"C:\Users\faiz\Desktop\AI\车牌-字符样本\车牌-字符样本\chars\" + label;
            //    Console.WriteLine("{0}", filePath);
            //    List<string> files = getSampleFiles(filePath);
            //    ImgFiles.Add(files);
            //}
            for (int index = (int)PlateChar.A; index <= (int)PlateChar._9; index++)
            {
                if (index >= 28 && index <= 37)
                {
                    string labelForNumber = "_" + (index - 28).ToString();
                    string filePath       = path + labelForNumber;//@"C:\Users\faiz\Desktop\AI\车牌-字符样本\车牌-字符样本\chars\"
                    Console.WriteLine("{0}", filePath);
                    List <string> files = getSampleFiles(filePath);
                    ImgFiles.Add(files);
                }
                else
                {
                    PlateChar plateChar    = (PlateChar)index;
                    string    labelForWord = plateChar.ToString();
                    string    filePath     = path + labelForWord;//@"C:\Users\faiz\Desktop\AI\车牌-字符样本\车牌-字符样本\chars\"
                    Console.WriteLine("{0}", filePath);
                    List <string> files = getSampleFiles(filePath);
                    ImgFiles.Add(files);
                }
            }
            //现在主要是要识别广东车牌
            List <string> exFiles = getSampleFiles(path + PlateChar.粤.ToString());

            ImgFiles.Add(exFiles);

            for (int index1 = 0; index1 < ImgFiles.Count - 1; index1++)
            {
                for (int index2 = 0; index2 < ImgFiles.ElementAt(index1).Count; index2++)
                {
                    TrainStruct trainData;
                    trainData.file  = ImgFiles.ElementAt(index1).ElementAt(index2);
                    trainData.label = index1 + 2;
                    svmData.Add(trainData);
                }
            }
            //最后再添加东的数据
            for (int index = 0; index < ImgFiles.ElementAt(ImgFiles.Count - 1).Count; index++)
            {
                TrainStruct trainData;
                trainData.file  = ImgFiles.ElementAt(ImgFiles.Count - 1).ElementAt(index);
                trainData.label = (int)PlateChar.粤;
                svmData.Add(trainData);
            }

            Mat samples   = new Mat();
            Mat responses = new Mat();

            //读取数据并进行处理
            for (int index = 0; index < svmData.Count; index++)
            {
                //以灰度的方式读取图片
                Mat img = Cv2.ImRead(svmData[index].file, ImreadModes.Grayscale);
                //剔除无用数据
                if (img.Data == null)
                {
                    Console.WriteLine("failed to load image {0}", svmData[index].file);
                }
                //对图片进行二值化
                Mat dst = new Mat();
                Cv2.Threshold(img, dst, 1, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary);
                Mat feature = GetCharSvmHOGFeatures(dst);
                //获取HOG特征
                feature = feature.Reshape(1, 1);
                samples.PushBack(feature);
                responses.PushBack(Int2Mat(svmData[index].label));
            }
            // 训练数据的格式,OpenCV规定 samples 中的数据都是需要32位浮点型
            // 因为TrainData::create 第一个参数是规定死的要cv_32F
            samples.ConvertTo(samples, MatType.CV_32F);
            // samples 将图片和样本标签合并成为一个训练集数据
            // 第二个参数的原因是,我们的samples 中的每个图片数据的排列都是一行
            if (PlateChar_SVM.Train(samples, responses))
            {
                Console.WriteLine("Trained success!!!");
                PlateChar_SVM.Save(@"E:\工作文件夹(workplace)\VSworkplace\PlateRecog\charRecog.xml");
                Console.WriteLine("\".xml\"has been written!!1");
            }
            else
            {
                Console.WriteLine("failed to train data");
            }
        }