emguCv3.x 实现字符分割,轮廓检测
/// <summary> /// 获取区域 /// </summary> /// <param name="bitmap"></param> /// <param name="graybtm"></param> /// <returns></returns> public static Bitmap FindBundingBox(Bitmap bitmap, out Bitmap graybtm,out List<Rectangle> rects) { Image<Bgr, byte> img = new Image<Bgr, byte>(bitmap); Image<Gray, byte> gray = new Image<Gray, byte>(img.Width, img.Height); Image<Bgr, byte> resuImage = new Image<Bgr, byte>(img.Width, img.Height); Image<Gray, byte> dnc = new Image<Gray, byte>(img.Width, img.Height); CvInvoke.CvtColor(img, gray, ColorConversion.Bgra2Gray);//灰度化 //做一下膨胀,x与y方向都做,但系数不同 var kernal = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(4, 4), new Point(1, 1)); CvInvoke.Erode(gray, gray, kernal, new Point(0, 2), 1, BorderType.Default, new MCvScalar()); //CvInvoke.Canny(gray, gray, 100, 60); CvInvoke.Threshold(gray, gray, 100, 255, ThresholdType.BinaryInv | ThresholdType.Otsu);//二值化 //检测连通域,每一个连通域以一系列的点表示,FindContours方法只能得到第一个域 graybtm = gray.ToBitmap(); VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint(); CvInvoke.FindContours(gray, contours, dnc, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple); var color = new MCvScalar(0, 0, 255); Console.WriteLine(contours.Size); rects = new List<Rectangle>(); //开始遍历 for (int i = 0; i < contours.Size; i++) { //得到这个连通区域的外接矩形 var rect = CvInvoke.BoundingRectangle(contours[i]); //如果高度不足,或者长宽比太小,认为是无效数据,否则把矩形画到原图上 if (rect.Height > 2 && rect.Width > 2) { rects.Add(rect); CvInvoke.DrawContours(resuImage, contours, i, color); } } return img.ConcateVertical(resuImage).ToBitmap(); }
private void StandardRects() { List<Rectangle> removeList=new List<Rectangle>(); foreach (var item in glbRect) { if (glbRect.Exists(o => o.Contains(item) && o!=item)) { removeList.Add(item); } } glbRect.RemoveAll(o => removeList.Contains(o)); glbRect=glbRect.OrderBy(o => o.X).ToList(); lb_count.Text = "轮廓总数:" + glbRect.Count; }