//得到图片的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");
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        //颜色法
        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);
        }