//得到图片的HOG特征 public static Mat GetPlateSvmHOGFeatures(Mat img) { float[] descriptor = PlateCategory_SVM.ComputeHogDescriptors(img); Mat feature = Float2Mat(descriptor); return(feature); }
//对是否为车牌进行训练 public static void TrainSVMDataForPlateRecog() { Console.WriteLine("preparing for training data!!!!"); List <TrainStruct> svmData = new List <TrainStruct>(); List <string> posImgFiles = getSampleFiles(@"E:\工作文件夹(workplace)\VSworkplace\PlateRecog\PlateRecog\普通车牌"); List <string> negImgFiles = getSampleFiles(@"E:\工作文件夹(workplace)\VSworkplace\PlateRecog\PlateRecog\非车牌"); //添加将正样本数据 for (int index = 0; index < posImgFiles.Count; index++) { TrainStruct trainData; trainData.file = posImgFiles[index]; trainData.label = 1; svmData.Add(trainData); } //添加负样本数据 for (int index = 0; index < negImgFiles.Count; index++) { TrainStruct trainData; trainData.file = negImgFiles[index]; trainData.label = -1; svmData.Add(trainData); } Mat samples = new Mat(); Mat responses = new Mat(); //读取数据并进行处理 for (int index = 0; index < svmData.Count; index++) { //以灰度的方式读取图片 Mat img = Cv2.ImRead(svmData[index].file, ImreadModes.Grayscale); //剔除无用数据 if (img.Data == null) { Console.WriteLine("failed to load image {0}", svmData[index].file); } //对图片进行二值化 Mat dst = new Mat(); Cv2.Threshold(img, dst, 1, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary); //gray.Threshold(1, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary) Mat feature = GetPlateSvmHOGFeatures(dst); //获取HOG特征 feature = feature.Reshape(1, 1); samples.PushBack(feature); responses.PushBack(Int2Mat(svmData[index].label)); } // 训练数据的格式,OpenCV规定 samples 中的数据都是需要32位浮点型 // 因为TrainData::create 第一个参数是规定死的要cv_32F samples.ConvertTo(samples, MatType.CV_32F); // samples 将图片和样本标签合并成为一个训练集数据 // 第二个参数的原因是,我们的samples 中的每个图片数据的排列都是一行 if (PlateCategory_SVM.Train(samples, responses)) { Console.WriteLine("Traing!!!"); PlateCategory_SVM.Save(@"E:\工作文件夹(workplace)\VSworkplace\PlateRecog\plateRecog.xml"); } else { Console.WriteLine("failed to train data"); } }
private static List <PlateInfo> LocatePlatesBySobel(Mat matSource, int blur_Size = 5, int sobel_Scale = 1, int sobel_Delta = 0, int sobel_X_Weight = 1, int sobel_Y_Weight = 0, int morph_Size_Width = 17, int morph_Size_Height = 3, int minWidth = 60, int maxWidth = 180, int minHeight = 18, int maxHeight = 80, float minRatio = 0.15f, float maxRatio = 0.70f) { List <PlateInfo> plateInfos = new List <PlateInfo>(); if (matSource.Empty()) { return(plateInfos); } Mat blur = null; Mat gray = null; blur = matSource.GaussianBlur(new OpenCvSharp.Size(blur_Size, blur_Size), 0, 0, BorderTypes.Default); gray = blur.CvtColor(ColorConversionCodes.BGR2GRAY); // 对图像进行Sobel 运算,得到的是图像的一阶水平方向导数。 // Generate grad_x and grad_y MatType ddepth = MatType.CV_16S; Mat grad_x = gray.Sobel(ddepth, 1, 0, 3, sobel_Scale, sobel_Delta, BorderTypes.Default); Mat abs_grad_x = grad_x.ConvertScaleAbs(); Mat grad_y = gray.Sobel(ddepth, 0, 1, 3, sobel_Scale, sobel_Delta, BorderTypes.Default); Mat abs_grad_y = grad_y.ConvertScaleAbs(); Mat grad = new Mat(); Cv2.AddWeighted(abs_grad_x, sobel_X_Weight, abs_grad_y, sobel_Y_Weight, 0, grad); // 对图像进行二值化。将灰度图像(每个像素点有256 个取值可能)转化为二值图像(每个像素点仅有1 和0 两个取值可能)。 Mat threshold = grad.Threshold(0, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary); // 使用闭操作。对图像进行闭操作以后,可以看到车牌区域被连接成一个矩形装的区域。 Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(morph_Size_Width, morph_Size_Height)); Mat threshold_Close = threshold.MorphologyEx(MorphTypes.Close, element); Mat element_Erode = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5)); Mat threshold_Erode = threshold_Close.Erode(element_Erode); // Find 轮廓 of possibles plates 求轮廓。求出图中所有的轮廓。这个算法会把全图的轮廓都计算出来,因此要进行筛选。 OpenCvSharp.Point[][] contours = null; HierarchyIndex[] hierarchys = null; Cv2.FindContours(threshold_Erode, out contours, out hierarchys, RetrievalModes.External, ContourApproximationModes.ApproxNone); // 筛选。对轮廓求最小外接矩形,然后验证,不满足条件的淘汰。 for (int index = 0; index < contours.Length; index++) { Rect rectROI = Cv2.BoundingRect(contours[index]); if (VerifyPlateSize(rectROI.Size, minWidth, maxWidth, minHeight, maxHeight, minRatio, maxRatio)) { Mat matROI = matSource.SubMat(rectROI); PlateCategory plateCategory = PlateCategory_SVM.Test(matROI); if (plateCategory == PlateCategory.非车牌) { continue; } PlateInfo plateInfo = new PlateInfo(); plateInfo.OriginalRect = rectROI; plateInfo.OriginalMat = matROI; plateInfo.PlateCategory = plateCategory; plateInfo.PlateLocateMethod = PlateLocateMethod.Sobel法; plateInfos.Add(plateInfo); } } return(plateInfos); }
public static List <PlateInfo> LocatePlatesForAutoSample(Mat matSource, out Mat matProcess, int blur_Size = 5, int sobel_Scale = 1, int sobel_Delta = 0, int sobel_X_Weight = 1, int sobel_Y_Weight = 0, int morph_Size_Width = 17, int morph_Size_Height = 3, int minWidth = 60, int maxWidth = 180, int minHeight = 18, int maxHeight = 80, float minRatio = 0.15f, float maxRatio = 0.70f) { List <PlateInfo> plateInfos = new List <PlateInfo>(); Mat gray = null; Mat blur = null; if (matSource.Empty() || matSource.Rows == 0 || matSource.Cols == 0) { matProcess = new Mat(0, 0, MatType.CV_8UC1); return(plateInfos); } //灰度图 gray = matSource.CvtColor(ColorConversionCodes.BGR2GRAY); //高斯模糊图 blur = gray.GaussianBlur(new OpenCvSharp.Size(blur_Size, blur_Size), 0, 0, BorderTypes.Default); //HSV图 Mat hsv = matSource.CvtColor(ColorConversionCodes.BGR2HSV); //将HSV图分成H、S、V通道图 Mat[] hsvSplits = hsv.Split(); hsvSplits[2] = hsvSplits[2].EqualizeHist(); Mat hsvEqualizeHist = new Mat(); //合并通道图 Cv2.Merge(hsvSplits, hsvEqualizeHist); //提取蓝色 Scalar blueStart = new Scalar(100, 70, 70); Scalar blueEnd = new Scalar(140, 255, 255); Mat blue = hsvEqualizeHist.InRange(blueStart, blueEnd); //提取黄色 Scalar yellowStart = new Scalar(15, 70, 70); Scalar yellowEnd = new Scalar(40, 255, 255); Mat yellow = hsvEqualizeHist.InRange(yellowStart, yellowEnd); Mat add = blue + yellow; //二值化 Mat threshold = add.Threshold(0, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary); Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(morph_Size_Width, morph_Size_Height)); //闭操作 Mat threshold_Close = threshold.MorphologyEx(MorphTypes.Close, element); Mat element_Erode = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3)); Mat threshold_Erode = threshold_Close.Erode(element_Erode); matProcess = threshold_Erode; OpenCvSharp.Point[][] contours = null; HierarchyIndex[] hierarchys = null; Cv2.FindContours(threshold_Erode, out contours, out hierarchys, RetrievalModes.External, ContourApproximationModes.ApproxNone); int isPlateCount = 0; for (int index = 0; index < contours.Length; index++) { RotatedRect rotatedRect = Cv2.MinAreaRect(contours[index]); Rect rectROI = Cv2.BoundingRect(contours[index]); if (VerifyPlateSize(rectROI.Size, minWidth, maxWidth, minHeight, maxHeight, minRatio, maxRatio)) { Mat matROI = matSource.SubMat(rectROI); PlateCategory plateCategory = PlateCategory_SVM.Test(matROI); if (plateCategory != PlateCategory.非车牌) { isPlateCount++; } PlateInfo plateInfo = new PlateInfo(); plateInfo.RotatedRect = rotatedRect; plateInfo.OriginalRect = rectROI; plateInfo.OriginalMat = matROI; plateInfo.PlateCategory = plateCategory; plateInfo.PlateLocateMethod = PlateLocateMethod.颜色法; plateInfos.Add(plateInfo); } } if (isPlateCount > 0) { return(plateInfos); } blur = matSource.GaussianBlur(new OpenCvSharp.Size(blur_Size, blur_Size), 0, 0, BorderTypes.Default); gray = blur.CvtColor(ColorConversionCodes.BGR2GRAY); // 对图像进行Sobel 运算,得到的是图像的一阶水平方向导数。 // Generate grad_x and grad_y MatType ddepth = MatType.CV_16S; Mat grad_x = gray.Sobel(ddepth, 1, 0, 3, sobel_Scale, sobel_Delta, BorderTypes.Default); Mat abs_grad_x = grad_x.ConvertScaleAbs(); Mat grad_y = gray.Sobel(ddepth, 0, 1, 3, sobel_Scale, sobel_Delta, BorderTypes.Default); Mat abs_grad_y = grad_y.ConvertScaleAbs(); Mat grad = new Mat(); Cv2.AddWeighted(abs_grad_x, sobel_X_Weight, abs_grad_y, sobel_Y_Weight, 0, grad); // 对图像进行二值化。将灰度图像(每个像素点有256 个取值可能)转化为二值图像(每个像素点仅有1 和0 两个取值可能)。 threshold = grad.Threshold(0, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary); // 使用闭操作。对图像进?行行闭操作以后,可以看到车牌区域被连接成一个矩形装的区域。 element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(morph_Size_Width, morph_Size_Height)); threshold_Close = threshold.MorphologyEx(MorphTypes.Close, element); element_Erode = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5)); threshold_Erode = threshold_Close.Erode(element_Erode); matProcess = threshold_Erode; // Find 轮廓 of possibles plates 求轮廓。求出图中所有的轮廓。这个算法会把全图的轮廓都计算出来,因此要进? 行行筛选。 contours = null; hierarchys = null; Cv2.FindContours(threshold_Erode, out contours, out hierarchys, RetrievalModes.External, ContourApproximationModes.ApproxNone); // 筛选。对轮廓求最?小外接矩形,然后验证,不不满?足条件的淘汰。 for (int index = 0; index < contours.Length; index++) { Rect rectROI = Cv2.BoundingRect(contours[index]); if (VerifyPlateSize(rectROI.Size, minWidth, maxWidth, minHeight, maxHeight, minRatio, maxRatio)) { RotatedRect rotatedRect = Cv2.MinAreaRect(contours[index]); Mat matROI = matSource.SubMat(rectROI); PlateCategory plateCategory = PlateCategory_SVM.Test(matROI); PlateInfo plateInfo = new PlateInfo(); plateInfo.RotatedRect = rotatedRect; plateInfo.OriginalRect = rectROI; plateInfo.OriginalMat = matROI; plateInfo.PlateCategory = plateCategory; plateInfo.PlateLocateMethod = PlateLocateMethod.Sobel法; plateInfos.Add(plateInfo); } } return(plateInfos); }
//颜色法 private static List <PlateInfo> LocatePlatesByColor(Mat matSource, int blur_Size = 5, int morph_Size_Width = 17, int morph_Size_Height = 3, int minWidth = 60, int maxWidth = 180, int minHeight = 18, int maxHeight = 80, float minRatio = 0.15f, float maxRatio = 0.70f) { List <PlateInfo> plateInfos = new List <PlateInfo>(); if (matSource.Empty()) { return(plateInfos); } Mat hsv = matSource.CvtColor(ColorConversionCodes.BGR2HSV); Mat[] hsvSplits = hsv.Split(); hsvSplits[2] = hsvSplits[2].EqualizeHist(); Mat hsvEqualizeHist = new Mat(); Cv2.Merge(hsvSplits, hsvEqualizeHist); Scalar blueStart = new Scalar(100, 70, 70); Scalar blueEnd = new Scalar(140, 255, 255); Mat blue = hsvEqualizeHist.InRange(blueStart, blueEnd); Scalar yellowStart = new Scalar(15, 70, 70); Scalar yellowEnd = new Scalar(40, 255, 255); Mat yellow = hsvEqualizeHist.InRange(yellowStart, yellowEnd); Mat add = blue + yellow; Mat threshold = add.Threshold(0, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary); Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(morph_Size_Width, morph_Size_Height)); Mat threshold_Close = threshold.MorphologyEx(MorphTypes.Close, element); Mat element_Erode = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3)); Mat threshold_Erode = threshold_Close.Erode(element_Erode); OpenCvSharp.Point[][] contours = null; HierarchyIndex[] hierarchys = null; Cv2.FindContours(threshold_Erode, out contours, out hierarchys, RetrievalModes.External, ContourApproximationModes.ApproxNone); for (int index = 0; index < contours.Length; index++) { Rect rectROI = Cv2.BoundingRect(contours[index]); if (VerifyPlateSize(rectROI.Size, minWidth, maxWidth, minHeight, maxHeight, minRatio, maxRatio)) { Mat matROI = matSource.SubMat(rectROI); PlateCategory plateCategory = PlateCategory_SVM.Test(matROI); if (plateCategory == PlateCategory.非车牌) { continue; } PlateInfo plateInfo = new PlateInfo(); plateInfo.OriginalRect = rectROI; plateInfo.OriginalMat = matROI; plateInfo.PlateCategory = plateCategory; plateInfo.PlateLocateMethod = PlateLocateMethod.颜色法; plateInfos.Add(plateInfo); } } return(plateInfos); }