//得到车牌的所有信息通过不同的方法 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++; } } }
//原始分割 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); }
// 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); }
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); }
//通过对数变换分割 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)); }
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)); }
//清除铆钉和边界 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); }
//展示字符 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); }