/// <summary> /// 字符分割 -- 保存 到 txt /// </summary> /// <param name="matPlate"></param> private String CharsSplit(Mat matPlate) { List <Mat> ListMat = my_Method.carCharSplit(matPlate); List <PlateCategory> category = Plate_SVM.TestList(ListMat); TextBox tx = new TextBox(); for (int index = 0; index < category.Count; index++) { if (category[index] == 0) { tx.AppendText(string.Format("{0}", "")); } else { tx.AppendText(string.Format("{0}", category[index])); } } string res = tx.Text.Replace("_", ""); if (res != null && res != "" && res.Length > 4) { res = this.SubChar(res); } return(res); }
//创建存放结果集的文件夹与文件 private void CreatFile() { //启动加载xml 在debug下 xml Plate_SVM.Load(Application.StartupPath + @"\MyTestChar.xml"); Plate_Car_SVM.Load(Application.StartupPath + @"\MyTestCar.xml"); String DirectoryPath = @"C:\test-results"; if (!Directory.Exists(DirectoryPath)) { Directory.CreateDirectory(DirectoryPath); } if (File.Exists(DirectoryPath + @"\No14866mresults.txt")) { File.Delete(DirectoryPath + @"\No14866mresults.txt"); FileStream fs = new FileStream(DirectoryPath + @"\No14866mresults.txt", FileMode.Create, FileAccess.ReadWrite);//创建写入文件 file = new StreamWriter(fs); } else { FileStream fs = new FileStream(DirectoryPath + @"\No14866mresults.txt", FileMode.Create, FileAccess.ReadWrite);//创建写入文件 file = new StreamWriter(fs); } }
private void OpenXML_Click(object sender, EventArgs e) { OpenFileDialog openDlg = new OpenFileDialog(); openDlg.Filter = "XML文件|*.xml"; DialogResult dlgResult = openDlg.ShowDialog(); if (dlgResult == DialogResult.OK) { Plate_SVM.Load(openDlg.FileName); } }
/// <summary> /// 保存训练数据XML /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnSaveXML_Click(object sender, EventArgs e) { SaveFileDialog saveDlg = new SaveFileDialog(); saveDlg.Filter = "XML文件|*.xml"; DialogResult dlgResult = saveDlg.ShowDialog(); if (dlgResult == DialogResult.OK) { Plate_SVM.Save(saveDlg.FileName); this.txtinfo.AppendText("保存-训练数据XML成功 \r\n "); } }
/// <summary> /// 显示lable 点击切割 /// </summary> /// <param name="matPlate"></param> /// <param name="panel"></param> private void CharsSplit(Mat matPlate, Panel panel) { panel.Controls.Clear();//清空 Console.WriteLine(panel.Name); List <Mat> ListMat = my_Method.carCharSplit(matPlate); //添加灰度图 this.GenerateROI(my_Method.matGray_car, panel, false); //添加二值图 this.GenerateROI(my_Method.matshoid, panel, false); //膨胀图 this.GenerateROI(my_Method.matDilate_car, panel, false); // this.GenerateROI(my_Method.matWithFalg_car, panel, false); //矩形 this.GenerateROI(my_Method.matWithRects, panel, false); // 分割出来的每个字符图 foreach (var item in ListMat) { this.GenerateROI(item, panel, false); } this.GenerateROI(my_Method.matWithRects, panel, false); List <PlateCategory> category = Plate_SVM.TestList(ListMat); TextBox tx = new TextBox(); for (int index = 0; index < category.Count; index++) { if (category[index] == 0) { tx.AppendText(string.Format("{0}", "")); } else { tx.AppendText(string.Format("{0}", category[index])); } } string res = tx.Text.Replace("_", ""); //for (int i = 0; i < res.Length; i++) //{ if (res != null && res != "" && res.Length > 4) { res = this.SubChar(res); } // 显示识别结果 this.lblCarText.Text = res; //} }
private void tvTest_AfterSelect(object sender, TreeViewEventArgs e) { if (e.Node.Level == 0) { return; } string fileName = e.Node.Tag as string; if (fileName == null) { return; } Mat matPreview = Cv2.ImRead(fileName); this.picImage.Image = matPreview.ToBitmap(); PlateCategory category = Plate_SVM.Test(matPreview); this.txtinfo.AppendText(string.Format("\r\n预测结果:{0}\r\n", category)); }
/// <summary> /// 开始训练 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnStart_Click(object sender, EventArgs e) { if (this.samplePath == "") { return; } List <PlateInfo> plateSamples = new List <PlateInfo>(); string[] subDirectories = Directory.GetDirectories(this.samplePath); for (int index = 0; index < subDirectories.Length; index++) { string subDirectory = subDirectories[index]; string shortDirectory = subDirectory.Substring(subDirectory.LastIndexOf(@"\") + 1); PlateCategory category = (PlateCategory)Enum.Parse(typeof(PlateCategory), shortDirectory); string[] fileNames = Directory.GetFiles(subDirectory, "*.jpg"); for (int i = 0; i < fileNames.Length; i++) { string fileName = fileNames[i]; this.txtinfo.AppendText(string.Format("{0} 类型:{1}\r\n", fileName, category)); Mat matPlate = Cv2.ImRead(fileName); PlateInfo plateInfo = new PlateInfo(); plateInfo.PlateMat = matPlate; plateInfo.Category = category; plateSamples.Add(plateInfo); } } //将样本的元数据转化为SVM的样品数据和标签数据 Mat trainData = new Mat(); Mat trainLabel = new Mat(plateSamples.Count, 1, MatType.CV_32SC1); for (int index = 0; index < plateSamples.Count; index++) { PlateInfo plateInfo = plateSamples[index]; float[] hog = Plate_SVM.GetHog(plateInfo.PlateMat); if (index == 0) { trainData = Mat.Zeros(plateSamples.Count, hog.Length, MatType.CV_32FC1); } for (int colIndex = 0; colIndex < hog.Length; colIndex++) { trainData.Set <float>(index, colIndex, hog[colIndex]); } trainLabel.Set <int>(index, 0, (int)plateInfo.Category); this.txtinfo.AppendText(hog.Length.ToString() + "\r\n"); } Plate_SVM.Train(trainData, trainLabel); this.txtinfo.AppendText("训练已完成\r\n"); }
/// <summary> /// 颜色交换 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void toolStripComboBox1_TextChanged(object sender, EventArgs e) { // 颜色法 this.HSVEvenimg = my_Method.ColorMethod(this.frameClone, 5, 50, 255, this.HSVEvenimg); this.picColorM.Image = this.HSVEvenimg.ToBitmap(); // this.GenerateROI(this.HSVEvenimg, this.panelColor, false); // 颜色区域 Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(11, 2)); // 定义点的二维数组 OpenCvSharp.Point[][] contours = null; HierarchyIndex[] hierarchies = null; contours = my_Method.ColorRange(element, contours, hierarchies, frameClone, this.HSVEvenimg, 5); string s = this.lblText.Text.Trim(); //图像显示识别结果 if (this.lblText.Text.Trim() != null && this.lblText.Text.Trim() != "") { String rest = this.lblText.Text.Trim(); if ((int)rest[0] < 127) { rest = rest.Remove(0, 1); } if (my_Method.bluenum > my_Method.greennum) { if (rest.Length > 7) { rest.Remove(7); } } if (my_Method.bluenum > my_Method.greennum) { if (rest.Length > 8) { rest.Remove(8); } } Regex reg = new Regex("[\u4e00-\u9fa5]+"); foreach (Match Chinese in reg.Matches(rest)) { int indexof = rest.IndexOf(Chinese.Value); rest = rest.Remove(indexof, 1); int has = Form_Main.hashRes.Count; if (Form_Main.hashRes.ContainsKey(Chinese.Value)) { rest = rest.Insert(indexof, Form_Main.hashRes[Chinese.Value].ToString()); } } my_Method.matWithFlag.PutText("result: " + rest, new OpenCvSharp.Point(50, 100), HersheyFonts.HersheyTriplex, 0.8, Scalar.Yellow, 2); } // 显示查找的轮廓 this.picMatWithFlag.Image = my_Method.matWithFlag.ToBitmap(); this.rectList.Clear(); for (int i = 0; i < contours.Length; i++) { // 轮廓的最小矩形 Rect rect = Cv2.BoundingRect(contours[i]); this.rectList.Add(rect); // 添加到集合 } // 遍历找到的矩形 然后截取出来 foreach (var item in this.rectList) { if (item.Width >= 40 && item.Width <= 2000 && item.Height >= 20 && item.Height <= 2000 && item.Width / item.Height > 0.8 && item.Width / item.Height < 5) { //SubMat 对矩形区域进行截取 matRoi = this.frameClone.SubMat(item); if (Plate_Car_SVM.TestCar(matRoi) == PlateCar.车牌) { // 显示截取的矩形 this.picRect.Image = matRoi.ToBitmap(); // 进行分割 List <Mat> ListMat = my_Method.carCharSplit(matRoi); List <PlateCategory> category = Plate_SVM.TestList(ListMat); TextBox tx = new TextBox(); for (int index = 0; index < category.Count; index++) { if (category[index] == 0) { tx.AppendText(string.Format("{0}", "")); } else { tx.AppendText(string.Format("{0}", category[index])); } } string res = tx.Text.Replace("_", ""); Console.WriteLine(res.Length + " : 第一个"); for (int i = 0; i < res.Length; i++) { // 判断第一个是不是汉字 不是就删除 // 不是汉字 if ((int)res[0] < 127 && res.Length > 1 && res != null && res != "") { res = res.Substring(1); // 显示识别结果 this.lblText.Text = res; } else { // 显示识别结果 this.lblText.Text = res; } } GC.Collect(); } } } }
public static List <Mat> carCharSplit(Mat matPlate) { Mat hsvmat = matPlate.CvtColor(ColorConversionCodes.BGR2HSV); Mat[] hsv = hsvmat.Split(); Mat h = hsv[0]; Mat s = hsv[1]; Mat v = hsv[2]; for (int i = 0; i < hsvmat.Rows; i++) { for (int j = 0; j < hsvmat.Cols; j++) { byte hvalue = h.At <byte>(i, j); //////////////////h通道/-///////////////////// // Console.WriteLine(hvalue + ":h"); byte svalue = s.At <byte>(i, j); //////////////////s通道/-///////////////////// byte vvalue = v.At <byte>(i, j); //////////////////v通道/-///////////////////// // printf("x=%d,y=%d,HSV: H=%d,S=%d,V=%d\n",i,j,hvalue,svalue,vvalue); if ((hvalue > 80 && hvalue < 130) && (svalue > 43 && svalue < 220) && (vvalue > 46 && vvalue < 255)) //hsv图像在蓝色区域里 { //蓝色+1 bluenum++; } else if ((hvalue > 11 && hvalue < 34) && (svalue > 43 && svalue < 255) && (vvalue > 46 && vvalue < 255))//hsv在黄色区域里 { //黄色+1 yellownum++; } else if ((hvalue > 0 && hvalue < 180) && (svalue > 0 && svalue < 255) && (vvalue > 0 && vvalue < 46))//hsv在黑色区域里 { blacknum++; //黑色+1 } else if ((hvalue > 0 && hvalue < 180) && (svalue > 0 && svalue < 30) && (vvalue > 46 && vvalue < 220))//hsv在白色区域里 { //白色+1 whitenum++; } else if ((hvalue > 60 && hvalue < 90) && (svalue > 43 && svalue < 255) && (vvalue > 46 && vvalue < 255))//hsv在绿色区域里 { //绿色+1 greennum++; } else { //其他颜色 othernum++; } } } Console.WriteLine(greennum + ":绿色"); Console.WriteLine(hsvmat.Rows * hsvmat.Cols + ":总"); Console.WriteLine(yellownum + ":黄色"); Console.WriteLine(bluenum + ":蓝色"); // 灰度 matGray_car = matPlate.CvtColor(ColorConversionCodes.BGR2GRAY); //二值化 Mat matshoid_th = matGray_car.Threshold(0, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary); matshoid = new Mat(); // 判断 取反 否 if (bluenum < yellownum && yellownum > greennum) { // 取反 matshoid = 255 - matshoid_th; } else if (bluenum > yellownum && bluenum > greennum) { matshoid = matGray_car.Threshold(0, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary); } else if (greennum > yellownum && greennum > bluenum) { // 取反 matshoid = 255 - matshoid_th; } else { matshoid = matGray_car.Threshold(0, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary); } // 车牌高度大于20的去除边框和柳钉 Mat clearBorder = new Mat(); Mat clearMoDing = new Mat(); if (matshoid.Height > 22) { // 去除边框 clearBorder = ClearBorder(matshoid); // 去除柳钉 clearMoDing = ClearMaoding(matshoid, 4); } else if (matshoid.Height <= 22 && matshoid.Height > 20) { // 去除边框 clearBorder = ClearBorder(matshoid); // 去除柳钉 clearMoDing = ClearMaoding(matshoid, 3); } else { clearMoDing = matshoid; } // 膨胀 Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(1, 1)); matDilate_car = clearMoDing.MorphologyEx(MorphTypes.Dilate, element); //点的二维数组 OpenCvSharp.Point[][] contours = null; HierarchyIndex[] hierarchyIndexs = null; matDilate_car.FindContours(out contours, out hierarchyIndexs, RetrievalModes.External, ContourApproximationModes.ApproxSimple); matWithFalg_car = matPlate.Clone(); matWithFalg_car.DrawContours(contours, -1, Scalar.Red); matWithRects = matPlate.Clone(); // 创建集合 存储分割后的图片 -- 用于 识别 List <Mat> ListMat = new List <Mat>(); // 切割的矩形 图 List <Rect> ListRect = new List <Rect>(); for (int index = 0; index < contours.Length; index++) { Rect rect = Cv2.BoundingRect(contours[index]); ListRect.Add(rect); matWithRects.Rectangle(rect, Scalar.Red); } // 对分割的字符排序 SortRectsByLeft_ASC(ListRect); foreach (var rect in ListRect) { Mat matchar = matPlate.SubMat(rect); // 切割矩形 Console.WriteLine("========= 宽:" + matchar.Width + " 高:" + matchar.Height); // 判断 太小的不要 if (matchar.Width >= 3 && matchar.Height >= 10) { PlateCategory plateCate = Plate_SVM.Test(matchar); ListMat.Add(matchar); Console.WriteLine(ListMat.Count + " 个"); } Console.WriteLine("========= 宽:" + rect.Width + " 高:" + rect.Height + " X:" + rect.X + " Y:" + rect.Y); } return(ListMat); }