Emgucv粗略抠取车牌

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);
        } 
    }
}

这段代码可以抠出类似车牌的矩形框,不过因为本人有点赖,没有把所有抠出来的矩形保存为图片,只保存了第一个抠出来的矩形,有兴趣的人在实际运行的时候再修改修改。

你可能感兴趣的:(Emgucv粗略抠取车牌)