OpenCv案例(十一):基于OpenCvSharp识别图像中目标并分类

概要

        本篇文章主要分享基于OpenCvSharp库,使用SVM(想要详细了解什么是SVM点这里SVM简解,还有详解:SVM详解,OpenCv中SVM参数详解:官方入口)进行目标物体的识别与分类;案例中识别的随机撒放的螺丝、螺母、垫片、方片,三角扣并且标签分类;

        原图如下所示:                        

OpenCv案例(十一):基于OpenCvSharp识别图像中目标并分类_第1张图片  

        处理结果:

 OpenCv案例(十一):基于OpenCvSharp识别图像中目标并分类_第2张图片

主要处理步骤:

  1. 图像预处理
  2. 特征提取
  3. 模型训练
  4. 识别分类

详细流程:

        图像预处理。

  •  图像降噪,背景消除,代码中使用的时盒子滤波去噪(BoxFilter)。由于拍摄环境相对理想,所以处理起来不复杂,模糊图像获得背景图片,原图与背景图做差,达到背景去除的目的。然后图像二值化,便于后续处理。

          下图所示: 

OpenCv案例(十一):基于OpenCvSharp识别图像中目标并分类_第3张图片

        代码如下:

        public Mat CalculateLightPattern(Mat mat)
        {
            Mat pattern = new Mat();
            Cv2.Blur(mat, pattern, new Size(mat.Cols, mat.Width));
            return pattern;
        }

        public Mat RemoveBgm(Mat img, Mat pattern)
        {
            Mat result = new Mat();
            Mat img32 = new Mat();
            Mat pattern32 = new Mat();
            img.ConvertTo(img32, MatType.CV_32F);
            pattern.ConvertTo(pattern32, MatType.CV_32F);
            result = 1 - (pattern32 / img32);
            result = result * 255;
            result.ConvertTo(result, MatType.CV_8U);
            return result;
        }
        public Mat PreProcessImg(Mat input)
        {
            Cv2.CvtColor(input, input, ColorConversionCodes.BGR2GRAY);
            Mat result = new Mat();
            Mat imgNoise = new Mat();
            imgNoise = BoxFilter(input, MatType.CV_8UC3, new Size(3, 3)); //MedBlurImage(input);//

            //remove background
            Mat imgNoLight = new Mat();
            Mat lightPattern = CalculateLightPattern(imgNoise);
            imgNoLight = RemoveBgm(imgNoise, lightPattern);
            //Cv2.ImShow("imgNoLight", imgNoLight);
            //Cv2.WaitKey(0);
            Cv2.Threshold(imgNoLight, result, 200, 255, ThresholdTypes.Binary);
            //Mat morphImg = MorphImage(result, MorphShapes.Rect, MorphTypes.Open, 2, new OpenCvSharp.Size(3, 3));

            //Cv2.WaitKey(0);
            //Rect rect = new Rect(100, 100, 500, 400);
            //Mat mat = new Mat(result, rect);
            //Cv2.ImShow(DateTime.Now.ToString("yyyyMMddHHmmssfff") + "morphImg", mat);
            return result;
        }

             

     

  • 目标提取,代码中使用OpenCvSharp中ConnectedComponentsWithStats方法,将处理好的二值图像进行像素连接,标记目标。若邻接像素有相同值,则连接起来。从而获得目标图像形状。

                处理结果下图所示:             

OpenCv案例(十一):基于OpenCvSharp识别图像中目标并分类_第4张图片

                代码如下:

        /// 
        /// 初步目标检测
        /// 
        /// 
        /// 
        public int TargetDectation(string path)
        {
            //读取图像
            Mat imageRGB = Cv2.ImRead(path, ImreadModes.AnyColor);
            Mat imageGray = new Mat();
            if (imageRGB.Empty())
            {
                return -1;
            }
            Cv2.CvtColor(imageRGB, imageGray, ColorConversionCodes.RGB2GRAY);
            Cv2.ImShow("Gray", imageGray);

            //降噪
            Mat blur = BoxFilter(imageGray, MatType.CV_8UC3, new Size(5, 5));//5,5 ,0,0
            //获取背景
            Mat imgPattern = CalculateLightPattern(blur);
            //移除背景
            Mat newGray = RemoveBgm(blur, imgPattern);
            Cv2.ImShow("newGray", newGray);
            //阈值化
            Mat imageThr = new Mat();
            Cv2.Threshold(newGray, imageThr, 50, 255, ThresholdTypes.Binary);
            Cv2.ImShow("thr", imageThr);
            //通过连通组件算法分割
            imageThr = MorphImage(imageThr, MorphShapes.Ellipse, MorphTypes.Open, 2, new Size(3, 3));

            Mat labels = new Mat();
            Mat stats = new Mat();
            Mat centroids = new Mat();
            /*
             以下是大概的代码,其中值得注意的是ConnectedComponentsWithStats函数的三个参数labelMat, stats, centroids。           
            1、在python、c++版本的opencv里面和OpencvSharp的使用有所区别,OpencvSharp返回的是Mat。
            2、OpencvSharp版本里面centroids是2列若干行的矩阵,是64FC1所以取值形式centroids.At(h, 0),每一行的两个值,就是质

你可能感兴趣的:(OpenCVSharp视觉学习,计算机视觉,人工智能,opencv)