//自动样品分割 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>()); //返回?长度为零的集合 }
public static Mat GetCharSvmHOGFeatures(Mat img) { float[] descriptor = PlateChar_SVM.ComputeHogDescriptors(img); Mat feature = Float2Mat(descriptor); return(feature); }
// 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); }
//对分割好的字符进行识别,并得到字符数组 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); }
//对字符进行训练 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"); } }