using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Emgu.CV; using Emgu.CV.Structure; using Emgu.Util; using System.Drawing; using Emgu.CV.Util; using System.Collections; namespace Final.Tool { class Pictrue { public static ArrayList list = new ArrayList(); public static void preDeal(String path) { list.Clear(); Image<Bgr, byte> src = new Image<Bgr, byte>(path); Image<Gray, byte> graySrc = src.Convert<Gray, byte>(); //CvInvoke.cvSmooth(graySrc.Ptr,graySrc.Ptr,Emgu.CV.CvEnum.SMOOTH_TYPE.CV_GAUSSIAN,3,3,0,0); Image<Gray, byte> sobel = new Image<Gray, byte>(path); CvInvoke.cvSobel(graySrc.Ptr,sobel.Ptr,2,0,3); CvInvoke.cvNamedWindow("sobel"); CvInvoke.cvShowImage("sobel", sobel); CvInvoke.cvThreshold(sobel.Ptr,sobel.Ptr,0,255,Emgu.CV.CvEnum.THRESH.CV_THRESH_OTSU); //自定义1*3的核进行X方向的膨胀腐蚀 IntPtr mask = CvInvoke.cvCreateStructuringElementEx(3, 1, 1, 0, Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_RECT, new IntPtr());//自定义一个核 CvInvoke.cvDilate(sobel.Ptr, sobel.Ptr, mask, 10);//X方向膨胀连通数字 CvInvoke.cvErode(sobel.Ptr, sobel.Ptr, mask, 16);//X方向腐蚀去除碎片 CvInvoke.cvDilate(sobel.Ptr, sobel.Ptr, mask, 10); //X方向膨胀回复形态 //自定义3*1的核进行Y方向的膨胀腐蚀 mask = CvInvoke.cvCreateStructuringElementEx(1, 3, 0, 1, Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_RECT, new IntPtr());//自定义一个核 CvInvoke.cvErode(sobel.Ptr, sobel.Ptr, mask, 1);// Y方向腐蚀去除碎片 CvInvoke.cvDilate(sobel.Ptr, sobel.Ptr, mask, 6);//回复形态 CvInvoke.cvNamedWindow("sobel2"); CvInvoke.cvShowImage("sobel2", sobel); //轮廓检测: IntPtr storage = CvInvoke.cvCreateMemStorage(0); MCvSeq comp1 = new MCvSeq(); comp1.ptr = new IntPtr(); IntPtr Dyncontour = new IntPtr(); int n = CvInvoke.cvFindContours(sobel.Ptr, storage, ref Dyncontour, StructSize.MCvContour, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_CCOMP, Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, new Point(0, 0)); Seq<Point> DyncontourTemp1 = new Seq<Point>(Dyncontour, null);//方便对IntPtr类型进行操作 Seq<Point> DyncontourTemp=DyncontourTemp1; Image<Bgr, byte> tempContImg = new Image<Bgr, byte>(path); double area; for (; DyncontourTemp != null && DyncontourTemp.Ptr.ToInt32() != 0; DyncontourTemp = DyncontourTemp.HNext) { Rectangle rect = CvInvoke.cvBoundingRect(DyncontourTemp, false); if (rect.Width > 2.8 * rect.Height && rect.Width < 3.5 * rect.Height)// { //抠到图了 Image<Bgr, byte> dst = new Image<Bgr, byte>(rect.Width,rect.Height); CvInvoke.cvSetImageROI(tempContImg.Ptr,rect); CvInvoke.cvCopy(tempContImg.Ptr,dst.Ptr,new IntPtr()); list.Add(dst); CvInvoke.cvSaveImage("p1.jpg",dst,new IntPtr()); CvInvoke.cvResetImageROI(tempContImg); } CvInvoke.cvDrawContours(tempContImg.Ptr, DyncontourTemp, new MCvScalar(255, 255, 255), new MCvScalar(255, 255, 255), 0, 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, new Point(0, 0)); } //Rectangle rect = CvInvoke.cvBoundingRect(DyncontourTemp, false); CvInvoke.cvShowImage("cont",tempContImg); } } }
这段代码可以抠出类似车牌的矩形框,不过因为本人有点赖,没有把所有抠出来的矩形保存为图片,只保存了第一个抠出来的矩形,有兴趣的人在实际运行的时候再修改修改。