//Elvégzi a karakterek keresését a bemeneti képen és a bemeneti listába visszaírja a megtalált karakterek adatait. public Image <Bgr, Byte> ProcessImage(Image <Gray, byte> grayFrame, out List <int[]> foundXO) { Image <Bgr, Byte> rv = grayFrame.Copy().Convert <Bgr, Byte>(); //Kontraszt beállítás if (equalizeHist) { grayFrame._EqualizeHist(); } //Élsimítás Image <Gray, byte> smoothedGrayFrame = grayFrame.PyrDown(); smoothedGrayFrame = smoothedGrayFrame.PyrUp(); //Éldetektálás Image <Gray, byte> cannyFrame = null; if (noiseFilter) { cannyFrame = smoothedGrayFrame.Canny(cannyThreshold, cannyThreshold); } //Élsimítás if (blur) { grayFrame = smoothedGrayFrame; } //Bináris konvertálás CvInvoke.cvAdaptiveThreshold(grayFrame, grayFrame, 255, Emgu.CV.CvEnum.ADAPTIVE_THRESHOLD_TYPE.CV_ADAPTIVE_THRESH_MEAN_C, Emgu.CV.CvEnum.THRESH.CV_THRESH_BINARY, adaptiveThresholdBlockSize + adaptiveThresholdBlockSize % 2 + 1, adaptiveThresholdParameter); grayFrame._Not(); if (addCanny) { if (cannyFrame != null) { grayFrame._Or(cannyFrame); } } this.binarizedFrame = grayFrame; if (cannyFrame != null) { cannyFrame = cannyFrame.Dilate(3); } //Kontúrok kigyűjtése var sourceContours = grayFrame.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST); //Kontúrok szűrése contours = FilterContours(sourceContours, cannyFrame, grayFrame.Width, grayFrame.Height); //Minták rögzítése. lock (foundTemplates) foundTemplates.Clear(); samples.Clear(); lock (templates) Parallel.ForEach <Contour <Point> >(contours, (contour) => { var arr = contour.ToArray(); Template sample = new Template(arr, contour.Area, samples.templateSize); lock (samples) samples.Add(sample); if (!onlyFindContours) //Ha a keresendő karakterek mintáit rögzítjük, akkor ne fusson le. { FoundTemplateDesc desc = finder.FindTemplate(templates, sample); if (desc != null) { lock (foundTemplates) foundTemplates.Add(desc); } } } ); FilterByIntersection(ref foundTemplates); foundXO = new List <int[]>(); //A megtalált karaktereket rárajzolja a képre és összeállítja a kimeneti listát a karkaterek adatairól. foreach (FoundTemplateDesc found in foundTemplates) { Rectangle foundRect = found.sample.contour.SourceBoundingRect; Point p1 = new Point((foundRect.Left + foundRect.Right) / 2, foundRect.Top); string text = found.template.name; MCvFont f = new MCvFont(FONT.CV_FONT_HERSHEY_COMPLEX, 1.0, 1.0); if (text == "X" && foundRect.Area() < 4000 && foundRect.Area() > 1000) { rv.Draw(foundRect, new Bgr(0, 255, 0), 4); foundXO.Add(new int[5] { foundRect.Center().X, foundRect.Center().Y, 1, foundRect.Width, foundRect.Height }); } else if (text == "O" && foundRect.Area() < 4000 && foundRect.Area() > 1000) { rv.Draw(foundRect, new Bgr(0, 0, 255), 4); foundXO.Add(new int[5] { foundRect.Center().X, foundRect.Center().Y, 0, foundRect.Width, foundRect.Height }); } } return(rv); }
public Image <Bgr, Byte> ProcessImage(Image <Gray, byte> grayFrame, out List <int[]> foundXO) { Image <Bgr, Byte> rv = grayFrame.Copy().Convert <Bgr, Byte>(); if (equalizeHist) { grayFrame._EqualizeHist();//autocontrast } //smoothed Image <Gray, byte> smoothedGrayFrame = grayFrame.PyrDown(); smoothedGrayFrame = smoothedGrayFrame.PyrUp(); //canny Image <Gray, byte> cannyFrame = null; if (noiseFilter) { cannyFrame = smoothedGrayFrame.Canny(cannyThreshold, cannyThreshold); } //smoothing if (blur) { grayFrame = smoothedGrayFrame; } //binarize CvInvoke.cvAdaptiveThreshold(grayFrame, grayFrame, 255, Emgu.CV.CvEnum.ADAPTIVE_THRESHOLD_TYPE.CV_ADAPTIVE_THRESH_MEAN_C, Emgu.CV.CvEnum.THRESH.CV_THRESH_BINARY, adaptiveThresholdBlockSize + adaptiveThresholdBlockSize % 2 + 1, adaptiveThresholdParameter); // grayFrame._Not(); // if (addCanny) { if (cannyFrame != null) { grayFrame._Or(cannyFrame); } } // this.binarizedFrame = grayFrame; //dilate canny contours for filtering if (cannyFrame != null) { cannyFrame = cannyFrame.Dilate(3); } //find contours var sourceContours = grayFrame.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST); //filter contours contours = FilterContours(sourceContours, cannyFrame, grayFrame.Width, grayFrame.Height); //find templates lock (foundTemplates) foundTemplates.Clear(); samples.Clear(); lock (templates) Parallel.ForEach <Contour <Point> >(contours, (contour) => { var arr = contour.ToArray(); Template sample = new Template(arr, contour.Area, samples.templateSize); lock (samples) samples.Add(sample); if (!onlyFindContours) { FoundTemplateDesc desc = finder.FindTemplate(templates, sample); if (desc != null) { lock (foundTemplates) foundTemplates.Add(desc); } } } ); FilterByIntersection(ref foundTemplates); foundXO = new List <int[]>(); foreach (FoundTemplateDesc found in foundTemplates) { if (found.template.name.EndsWith(".png") || found.template.name.EndsWith(".jpg")) { continue; } Rectangle foundRect = found.sample.contour.SourceBoundingRect; Point p1 = new Point((foundRect.Left + foundRect.Right) / 2, foundRect.Top); string text = found.template.name; MCvFont f = new MCvFont(FONT.CV_FONT_HERSHEY_COMPLEX, 1.0, 1.0); //rv.Draw((found.angle*180/Math.PI).ToString(), ref f, foundRect.Center(), new Bgr(0, 0, 0)); if (text == "X" && foundRect.Area() < 4000 && foundRect.Area() > 1000) { rv.Draw(foundRect, new Bgr(0, 255, 0), 4); foundXO.Add(new int[5] { foundRect.Center().X, foundRect.Center().Y, 1, foundRect.Width, foundRect.Height }); } else if (text == "O" && foundRect.Area() < 4000 && foundRect.Area() > 1000) { rv.Draw(foundRect, new Bgr(0, 0, 255), 4); foundXO.Add(new int[5] { foundRect.Center().X, foundRect.Center().Y, 0, foundRect.Width, foundRect.Height }); } //rv.Draw(new CircleF(new PointF(foundRect.Center().X, foundRect.Center().Y), 10), new Bgr(0, 255, 0), 3); //e.Graphics.DrawRectangle(borderPen, foundRect); //e.Graphics.DrawString(text, font, bgBrush, new PointF(p1.X + 1 - font.Height / 3, p1.Y + 1 - font.Height)); //e.Graphics.DrawString(text, font, foreBrush, new PointF(p1.X - font.Height / 3, p1.Y - font.Height)); } return(rv); }