public void RecognitionByML(Image <Gray, byte> src) { for (int i = 0; i < this.CVQuestionList.Count; i++) { var q = this.CVQuestionList[i]; if (q.ResultStatus != QuestionResultStatus.Absence) { continue; } for (int j = 0; j < q.OptionRectList.Count; j++) { var rect = q.OptionRectList[j]; //智能识别 var queRect = rect.Rectangle; queRect.Offset(this.Area.Location); using (var copy = src.Copy(queRect)) { var isAnswer = MLearner.IsAnswer(copy); if (!q.Results.Contains(j) && isAnswer) { q.Results.Add(j); } new CVHelper().SaveMat(copy.Mat, "需要智能之别的" + isAnswer); } } } }
/// <summary> /// 该区域的图片 /// </summary> /// <param name="src"></param> /// <param name="myThreshold"></param> public void Recognition(Image <Gray, byte> src, int myThreshold = 180) { ////思路:第一次正常识别--->初步智能筛选---->再次智能筛选---》再次智能(如果未选,继续多次,如果多选) ////var src = new Image<Gray, byte>(bitmap); var thresholdMat = src.CopyBlank().Mat; CvInvoke.Threshold(src, thresholdMat, myThreshold, 255, Emgu.CV.CvEnum.ThresholdType.BinaryInv); new CVHelper().SaveMat(src.Mat, "原始的"); //思路 open -膨胀 //形态学膨胀 Mat mat_dilate = CVHelper.MyDilateS(thresholdMat, Emgu.CV.CvEnum.MorphOp.Open); new CVHelper().SaveMat(mat_dilate, "Open行学"); mat_dilate = CVHelper.MyDilateS(mat_dilate, Emgu.CV.CvEnum.MorphOp.Dilate); new CVHelper().SaveMat(mat_dilate, "Dilate行学"); //补充偏移置换 //src = Max(src); foreach (var question in this.CVQuestionList) { for (int i = 0; i < question.OptionRectList.Count; i++) { var cvRect = question.OptionRectList[i]; //计算平均灰度值 //var fileName = $"{this.Name}第"; cvRect.CalVagGrayValueAndHist(src); //计算面积比 cvRect.CalAreaPercent(src); if (cvRect.AreaPercent > CVArea.valAreaPercent) { question.Results.Add(i); } } } //打印初步识别的 //new CommonUse().DrawRectCircleAndSave(src.Mat.Clone(), this.GetRectList(), $"{this.Name}-初步识别的", -this.Area.X, -this.Area.Y, points: this.GetResultPointList(false)); this.DrawDetail(src.Clone(), this.Name); //初步筛选 this.Check(); new CVHelper().DrawRectCircleAndSave(src.Mat.Clone(), this.GetRectList(false), $"{this.Name}-初步筛选结果", points: this.GetResultPointList(false)); //再次智能处理异常的 this.CVQuestionList.ForEach(q => { this.IntelligentChose(src, q); int total = 11; for (int i = 2; i <= total; i++) { if (q.ResultStatus == QuestionResultStatus.Right) { break; } else if (q.ResultStatus == QuestionResultStatus.Absence) { q.IntelligentChoseByAbsence(src, i); } } }); //再次通过神经网络识别 //this.RecognitionByML(); for (int i = 0; i < this.CVQuestionList.Count; i++) { var q = this.CVQuestionList[i]; if (q.ResultStatus != QuestionResultStatus.Absence) { continue; } //针对只有一个的选框的不适用人工智能网络) //if (this.GetOptionCount() == 1) //{ // continue; //} for (int j = 0; j < q.OptionRectList.Count; j++) { var rect = q.OptionRectList[j]; if (rect.AreaPercent == 0 && rect.AvgGrayValue == 0) { continue; } //智能识别 var queRect = rect.Rectangle; using (var copy = src.Copy(queRect)) { var isAnswer = MLearner.IsAnswer(copy); if (!q.Results.Contains(j) && isAnswer) { q.Results.Add(j); } new CVHelper().SaveMat(copy.Mat, "需要智能之别的" + isAnswer, dictory: "MLReg\\"); } } } //脱离原rectangle,再次智能筛选 try { DoMLAgain(src); } catch (Exception ex) { Console.WriteLine("再次智能之别是,发生错误"); Console.WriteLine(ex); } }
/// <summary> /// 再次智能识别 /// </summary> /// <param name="src"></param> private void DoMLAgain(Image <Gray, byte> src) { //正对使用了偏移块还不准的区域再次识别 if (!this.IsAbsence()) { return; } var cvHelper = new CVHelper(); var rectList = cvHelper.GetRectListFromBitmap(src.Bitmap, isAutoFillFull: true); if (rectList.Count != this.GetOptionCount())// || rectList.Count==1 针对只有一个的选框的不适用 { return; } var rectListDic = cvHelper.OrderRectList(rectList, this.IsOrderByRow()); var anwserDir = new Dictionary <int, List <int> >(); foreach (var key in rectListDic.Keys) { var queOptions = rectListDic[key]; var tmpResult = new List <int>(); for (int i = 0; i < queOptions.Count; i++) { var queRect = queOptions[i]; using (var copy = src.Copy(queRect)) { var isAnswer = MLearner.IsAnswer(copy); if (isAnswer) { tmpResult.Add(i); } #if DEBUG new CVHelper().SaveMat(copy.Mat, "再次智能之别的" + isAnswer, dictory: "MLReg2\\"); #endif } } anwserDir.Add(key, tmpResult); } //合并答案 foreach (var key in anwserDir.Keys) { var result = anwserDir[key]; if (this.CVQuestionList[key - 1].ResultStatus == QuestionResultStatus.Absence) { this.CVQuestionList[key - 1].Results = result; } } #if DEBUG //画出再次智能出来的框和识别出来的中心点 var tmpRectList = new List <Rectangle>(); var tmpPointList = new List <Point>(); foreach (var key in rectListDic.Keys) { tmpRectList.AddRange(rectListDic[key]); anwserDir[key].ForEach(i => { var rect = rectListDic[key][i]; var point = rect.Location; point.Offset(rect.Width / 2, rect.Height / 2); tmpPointList.Add(point); }); } cvHelper.DrawRectCircleAndSave(src.Mat, tmpRectList, "再次智能后", points: tmpPointList, dictory: "MLReg2\\"); #endif }