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

概要

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

        原图如下所示:                        

  

        处理结果:

 

主要处理步骤:

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

详细流程:

        图像预处理。

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

          下图所示: 

        代码如下:

        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方法,将处理好的二值图像进行像素连接,标记目标。若邻接像素有相同值,则连接起来。从而获得目标图像形状。

                处理结果下图所示:             

                代码如下:

        /// <summary>
        /// 初步目标检测
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        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<double>(h, 0)ÿ
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值