Пример #1
0
        //得到车牌的所有信息通过不同的方法
        public static PlateInfo GetPlateInfoByMutilMethod(PlateInfo plateInfo, PlateColor plateColor)
        {
            PlateInfo        plateInfoByOriginal = GetPlateInfo(plateInfo, plateColor, CharSplitMethod.原图);
            PlateInfo        plateInfoByGamma    = GetPlateInfo(plateInfo, plateColor, CharSplitMethod.伽马);
            PlateInfo        plateInfoByIndex    = GetPlateInfo(plateInfo, plateColor, CharSplitMethod.指数);
            PlateInfo        plateInfoByLog      = GetPlateInfo(plateInfo, plateColor, CharSplitMethod.对数);
            List <PlateInfo> plateInfos          = new List <PlateInfo>();

            if (plateInfoByOriginal.CharInfos != null && plateInfoByOriginal.CharInfos.Count != 0)
            {
                plateInfos.Add(plateInfoByOriginal);
            }
            if (plateInfoByGamma.CharInfos != null && plateInfoByGamma.CharInfos.Count != 0)
            {
                plateInfos.Add(plateInfoByGamma);
            }
            if (plateInfoByIndex.CharInfos != null && plateInfoByIndex.CharInfos.Count != 0)
            {
                plateInfos.Add(plateInfoByIndex);
            }
            if (plateInfoByLog.CharInfos != null && plateInfoByLog.CharInfos.Count != 0)
            {
                plateInfos.Add(plateInfoByLog);
            }
            if (plateInfos.Count == 0)
            {
                return(new PlateInfo());
            }
            plateInfos.Sort(new PlateInfoComparer_DESC());
            PlateInfo result = plateInfos[0];

            return(result);
        }
        //清除铆钉和边框
        public static Mat ClearMaodingAndBorder(Mat matGray, PlateColor plateColor)
        {
            Mat threshold = null;

            //注意后面的thresholdTypes参数,将黄牌的白底黑字转为和蓝牌一样的黑底白字
            switch (plateColor)
            {
            case PlateColor.BLUE:
                threshold = matGray.Threshold(1, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary);
                break;

            case PlateColor.YELLOW:
                threshold = matGray.Threshold(1, 255, ThresholdTypes.Otsu | ThresholdTypes.BinaryInv);
                break;

            case PlateColor.UNKNOW:
                threshold = matGray.Threshold(1, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary);
                break;
            }

            Mat matOfClearBoder            = ClearBorder(threshold);
            Mat matOfClearMaodingAndBorder = ClearMaoding(matOfClearBoder);

            return(matOfClearMaodingAndBorder);
        }
        public static void AutoProcessCharSegement(List <string> files, string savePath)
        {
            for (int i = 0; i < files.Count; i++)
            {
                Mat matIn   = new Mat(files[i]);
                Mat matGray = matIn.CvtColor(ColorConversionCodes.RGB2GRAY);

                PlateColor plateColor = GetPlateColor(matIn);
                Mat        matClear   = ClearMaodingAndBorder(matGray, plateColor);

                //找轮廓
                OpenCvSharp.Point[][] contours         = null;
                HierarchyIndex[]      hierarchyIndices = null;
                matClear.FindContours(out contours, out hierarchyIndices, RetrievalModes.External, ContourApproximationModes.ApproxNone);

                //求轮廓外接最小矩形
                List <Rect> rects       = new List <Rect>();
                Mat         matContours = matIn.Clone();
                for (int index = 0; index < contours.Length; index++)
                {
                    Rect rect = Cv2.BoundingRect(contours[index]);
                    if (VerifyRect(rect) &&
                        NotOnBorder(rect, matIn.Size()))
                    {
                        rects.Add(rect);
                        Cv2.Rectangle(matContours, rect, new Scalar(0, 0, 255), 1);
                    }
                }

                //去除内部矩形
                Mat matInner = matIn.Clone();
                rects = RejectInnerRectFromRects(rects);
                for (int index = 0; index < rects.Count; index++)
                {
                    Cv2.Rectangle(matInner, rects[index], new Scalar(0, 0, 255), 1);
                }



                //调整矩形大小
                Mat matAdjust = matIn.Clone();
                rects = AdjustRects(rects);
                for (int index = 0; index < rects.Count; index++)
                {
                    Cv2.Rectangle(matAdjust, rects[index], new Scalar(0, 0, 255), 1);
                }
                rects = GetSafeRects(matIn, rects);

                //保存切分的图片
                int j = 0;
                foreach (Rect rect in rects)
                {
                    Mat roi = new Mat(matIn, rects[j]);
                    Cv2.ImWrite(savePath + "\\sample_" + i.ToString() + "_" + j.ToString() + ".jpg", roi);
                    j++;
                }
            }
        }
Пример #4
0
        //原始分割
        public static List <CharInfo> SplitePlateByOriginal(Mat originalMat, Mat plateMat,
                                                            PlateColor plateColor,
                                                            CharSplitMethod charSplitMethod = CharSplitMethod.原图,
                                                            int leftLimit  = 0, int rightLimit     = 0,
                                                            int topLimit   = 0, int bottomLimit    = 0,
                                                            int minWidth   = 2, int maxWidth       = 30,
                                                            int minHeight  = 10, int maxHeight     = 80,
                                                            float minRatio = 0.08f, float maxRatio = 2f)
        {
            List <CharInfo> result = new List <CharInfo>();
            Mat             gray   = plateMat.CvtColor(ColorConversionCodes.BGR2GRAY);
            Mat             matOfClearMaodingAndBorder = ClearMaodingAndBorder(gray, plateColor);

            OpenCvSharp.Point[][] contours         = null;
            HierarchyIndex[]      hierarchyIndices = null;
            matOfClearMaodingAndBorder.FindContours(out contours, out hierarchyIndices,
                                                    RetrievalModes.External, ContourApproximationModes.ApproxNone);
            List <Rect> rects = new List <Rect>();

            //将轮廓使用RECT矩形框选出来
            for (int index = 0; index < contours.Length; index++)
            {
                Rect rect = Cv2.BoundingRect(contours[index]);
                if (NotOnBorder(rect, plateMat.Size(), leftLimit, rightLimit, topLimit, bottomLimit) &&
                    VerifyRect(rect, minWidth, maxWidth, minHeight, maxHeight, minRatio, maxRatio))
                {
                    rects.Add(rect);
                }
            }
            rects = RejectInnerRectFromRects(rects);
            //rects = RejectOutFromRects(rects);
            rects = AdjustRects(rects);
            if (rects.Count == 0)
            {
                return(result);
            }
            for (int index = 0; index < rects.Count; index++)
            {
                CharInfo plateCharInfo = new CharInfo();
                rects[index] = Utilities.GetSafeRect(rects[index], originalMat);

                Rect rectROI = rects[index];
                if (rectROI.Width == 0 && rectROI.Height == 0)
                {
                    continue;
                }
                Mat matROI = originalMat.SubMat(rectROI);
                plateCharInfo.OriginalMat     = matROI;
                plateCharInfo.OriginalRect    = rectROI;
                plateCharInfo.CharSplitMethod = charSplitMethod;
                result.Add(plateCharInfo);
            }
            result.Sort(new CharInfoLeftComparer());
            return(result);
        }
        //根据原图切割,返回该车牌上的字符的信息
        public static List <CharInfo> SplitePlateByOriginal(Mat matOriginal, Mat matPlate,
                                                            PlateColor plateColor,
                                                            int leftLimit  = 0, int rightLimit     = 0,
                                                            int topLimit   = 0, int bottomLimit    = 0,
                                                            int minWidth   = 2, int maxWidth       = 30,
                                                            int minHeight  = 10, int maxHeight     = 80,
                                                            float minRatio = 0.08f, float maxRatio = 2f)
        {
            List <CharInfo> result = new List <CharInfo>();

            Mat matGray  = matPlate.CvtColor(ColorConversionCodes.BGR2GRAY); //先将车牌转为灰度图,注意蓝黄牌会有很大区别
            Mat matClear = ClearMaodingAndBorder(matGray, plateColor);       //去除铆钉和边框

            //找轮廓
            OpenCvSharp.Point[][] contours         = null;
            HierarchyIndex[]      hierarchyIndices = null;
            matClear.FindContours(out contours, out hierarchyIndices, RetrievalModes.External, ContourApproximationModes.ApproxNone);
            //求轮廓外接最小矩形
            List <Rect> rects = new List <Rect>();

            for (int index = 0; index < contours.Length; index++)
            {
                Rect rect = Cv2.BoundingRect(contours[index]);
                if (VerifyRect(rect, minWidth, maxWidth, minHeight, maxHeight, minRatio, maxRatio) &&
                    NotOnBorder(rect, matPlate.Size(), leftLimit, rightLimit, topLimit, bottomLimit))
                {
                    rects.Add(rect);
                    // Cv2.Rectangle(matPlate, rect, new Scalar(0, 0, 255), 1);
                }
            }

            rects = RejectInnerRectFromRects(rects);  //去掉矩形内部的矩形
            rects = AdjustRects(rects);               //对矩形大小等进行调整
            rects = GetSafeRects(matOriginal, rects); //检查安全矩形

            if (rects.Count == 0)
            {
                return(result);
            }

            for (int index = 0; index < rects.Count; index++)
            {
                CharInfo plateCharInfo = new CharInfo();              //字符信息
                Rect     rectROI       = rects[index];                //字符所在矩形
                Mat      matROI        = matOriginal.SubMat(rectROI); //字符的图片
                plateCharInfo.OriginalMat  = matROI;
                plateCharInfo.OriginalRect = rectROI;

                result.Add(plateCharInfo);
            }
            return(result);
        }
Пример #6
0
        //
        public static PlateInfo GetPlateInfo(PlateInfo plateInfo, PlateColor plateColor, CharSplitMethod
                                             splitMethod)
        {
            PlateInfo result = new PlateInfo();

            result.PlateCategory     = plateInfo.PlateCategory;
            result.OriginalMat       = plateInfo.OriginalMat;
            result.OriginalRect      = plateInfo.OriginalRect;
            result.PlateLocateMethod = plateInfo.PlateLocateMethod;
            result.PlateColor        = plateColor;
            List <CharInfo> charInfos = new List <CharInfo>();

            switch (splitMethod)
            {
            case CharSplitMethod.伽马:
                charInfos = CharSegment_V3.SplitePlateByGammaTransform(plateInfo.OriginalMat,
                                                                       plateColor);
                break;

            case CharSplitMethod.指数:
                charInfos = CharSegment_V3.SplitePlateByIndexTransform(plateInfo.OriginalMat, plateColor);
                break;

            case CharSplitMethod.对数:
                charInfos = CharSegment_V3.SplitePlateByLogTransform(plateInfo.OriginalMat, plateColor);
                break;

            case CharSplitMethod.原图:
            default:
                charInfos = CharSegment_V3.SplitePlateByOriginal(plateInfo.OriginalMat,
                                                                 plateInfo.OriginalMat, plateColor);
                break;
            }
            //启动SVM识别字符并将其中的非字符去除
            for (int index = charInfos.Count - 1; index >= 0; index--)
            {
                CharInfo  charInfo  = charInfos[index];
                PlateChar plateChar = PlateChar_SVM.Test(charInfo.OriginalMat);
                if (plateChar == PlateChar.非字符)
                {
                    charInfos.RemoveAt(index);
                }
                charInfo.PlateChar = plateChar;
            }
            result.CharInfos = charInfos;
            //检测
            CheckLeftAndRightToRemove(result);
            CheckPlateColor(result);
            return(result);
        }
Пример #7
0
        public bool Update(string plateId, string plateNumber, PlateColor color, DbOperator dbOperator)
        {
            StringBuilder strSql = new StringBuilder();

            strSql.Append("update EmployeePlate set PlateNo=@PlateNo,Color=@Color,LastUpdateTime=@LastUpdateTime,HaveUpdate=@HaveUpdate");
            strSql.Append(" where PlateID=@PlateID");
            dbOperator.ClearParameters();
            dbOperator.AddParameter("PlateID", plateId);
            dbOperator.AddParameter("PlateNo", plateNumber);
            dbOperator.AddParameter("Color", (int)color);
            dbOperator.AddParameter("LastUpdateTime", DateTime.Now);
            dbOperator.AddParameter("HaveUpdate", SystemDefaultConfig.DataUpdateFlag);
            return(dbOperator.ExecuteNonQuery(strSql.ToString()) > 0);
        }
Пример #8
0
        //通过对数变换分割
        public static List <CharInfo> SplitePlateByLogTransform(Mat originalMat,
                                                                PlateColor plateColor,
                                                                int leftLimit  = 0, int rightLimit     = 0,
                                                                int topLimit   = 0, int bottomLimit    = 0,
                                                                int minWidth   = 2, int maxWidth       = 30,
                                                                int minHeight  = 10, int maxHeight     = 80,
                                                                float minRatio = 0.08f, float maxRatio = 2f)
        {
            Mat plateMat = Utilities.LogTransform(originalMat);

            return(SplitePlateByOriginal(originalMat, plateMat, plateColor,
                                         CharSplitMethod.对数,
                                         leftLimit, rightLimit,
                                         topLimit, bottomLimit,
                                         minWidth, maxWidth,
                                         minHeight, maxHeight,
                                         minRatio, maxRatio));
        }
Пример #9
0
        public static bool Update(string plateId, string plateNumber, PlateColor color)
        {
            if (string.IsNullOrWhiteSpace(plateId))
            {
                throw new ArgumentNullException("plateId");
            }
            if (string.IsNullOrWhiteSpace(plateNumber))
            {
                throw new ArgumentNullException("plateNumber");
            }

            IEmployeePlate factory = EmployeePlateFactory.GetFactory();

            using (DbOperator dbOperator = ConnectionManager.CreateReadConnection())
            {
                return(factory.Update(plateId, plateNumber, color, dbOperator));
            }
        }
        //通过gamma增强原图后在切割
        public static List <CharInfo> SplitePlateByGammaTransform(Mat originalMat,
                                                                  PlateColor plateColor,
                                                                  float gammaFactor = 0.40f,
                                                                  int leftLimit     = 0, int rightLimit     = 0,
                                                                  int topLimit      = 0, int bottomLimit    = 0,
                                                                  int minWidth      = 1, int maxWidth       = 30,
                                                                  int minHeight     = 10, int maxHeight     = 80,
                                                                  float minRatio    = 0.08f, float maxRatio = 2f)
        {
            Mat plateMat = Utilities.GammaTransform(originalMat, gammaFactor);

            return(SplitePlateByOriginal(originalMat, plateMat, plateColor,
                                         leftLimit, rightLimit,
                                         topLimit, bottomLimit,
                                         minWidth, maxWidth,
                                         minHeight, maxHeight,
                                         minRatio, maxRatio));
        }
Пример #11
0
        //清除铆钉和边界
        public static Mat ClearMaodingAndBorder(Mat gray, PlateColor plateColor)
        {
            Mat threshold = null;

            switch (plateColor)
            {
            case PlateColor.蓝牌:
                threshold = gray.Threshold(1, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary);
                break;

            case PlateColor.黄牌:
                threshold = gray.Threshold(1, 255, ThresholdTypes.Otsu | ThresholdTypes.BinaryInv);
                break;

            case PlateColor.未知:
                //这里的二值化记得拿去用一下下
                threshold = gray.Threshold(1, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary);
                break;
            }
            Mat matOfClearBoder            = ClearBorder(threshold);
            Mat matOfClearMaodingAndBorder = ClearMaoding(matOfClearBoder);

            return(matOfClearMaodingAndBorder);
        }
Пример #12
0
        //展示字符
        private void ProcessAndShowChars(Bitmap plate)
        {
            currentTabCount = 0;

            Mat matIn = plate.ToMat();

            AddTag("原图", matIn);

            // matIn = Utilities.GammaTransform(matIn);
            //AddTag("gamma增强", matIn);

            //matIn = Utilities.IndexTransform(matIn);
            //AddTag("指数增强", matIn);

            //matIn = Utilities.LogTransform(matIn);
            //AddTag("指数增强", matIn);

            //matIn = Utilities.LaplaceTransform(matIn);
            //AddTag("拉普拉斯",matIn);

            Mat matGray = matIn.CvtColor(ColorConversionCodes.RGB2GRAY);

            AddTag("灰度图", matGray);

            PlateColor plateColor = CharSegement.GetPlateColor(matIn);
            Mat        matClear   = CharSegement.ClearMaodingAndBorder(matGray, plateColor);

            AddTag("去边框与铆钉", matClear);

            //找轮廓
            OpenCvSharp.Point[][] contours         = null;
            HierarchyIndex[]      hierarchyIndices = null;
            matClear.FindContours(out contours, out hierarchyIndices, RetrievalModes.External,
                                  ContourApproximationModes.ApproxNone);

            //求轮廓外接最小矩形
            List <Rect> rects       = new List <Rect>();
            Mat         matContours = matIn.Clone();

            for (int index = 0; index < contours.Length; index++)
            {
                Rect rect = Cv2.BoundingRect(contours[index]);
                if (CharSegement.VerifyRect(rect) &&
                    CharSegement.NotOnBorder(rect, matIn.Size()))
                {
                    rects.Add(rect);
                    Cv2.Rectangle(matContours, rect, new Scalar(0, 0, 255), 1);
                }
            }
            AddTag("外接矩形", matContours);

            //去除内部矩形
            Mat matInner = matIn.Clone();

            rects = CharSegement.RejectInnerRectFromRects(rects);
            for (int index = 0; index < rects.Count; index++)
            {
                Cv2.Rectangle(matInner, rects[index], new Scalar(0, 0, 255), 1);
            }
            AddTag("去内部矩形", matInner);



            //调整矩形大小
            Mat matAdjust = matIn.Clone();

            rects = CharSegement.AdjustRects(rects);
            for (int index = 0; index < rects.Count; index++)
            {
                Cv2.Rectangle(matAdjust, rects[index], new Scalar(0, 0, 255), 1);
            }
            AddTag("调整大小", matAdjust);

            //得到安全矩形
            rects = CharSegement.GetSafeRects(matIn, rects);;

            //展示切割结果
            ShowSpliteImage(rects, matIn);
        }