OpenCv案例(一):OpenCvSharp识别图像中物体个数

需求:识别下图中零件的个数,包括其中有粘连部分;同理,可以识别零件以及其他产线样品数量;(如果不知如何使用OpenCvSharp,参考该文章(OpenCvSharp安装)中第一部分内容)

识别图像:

OpenCv案例(一):OpenCvSharp识别图像中物体个数_第1张图片

主要代码内容如下:

public Mat GetNumberByImg(Mat src, out int num)
        {
            num = 0;
            //图像灰度
            Mat matGray = new Mat();
            Cv2.CvtColor(src, matGray, ColorConversionCodes.BGR2GRAY);

            Mat blurMat = new Mat();
            Cv2.MedianBlur(matGray, blurMat, 5);
            Cv2.ImShow("blurMat", blurMat);

            //图像二值化
            Mat binaryMat = new Mat();
            Cv2.Threshold(blurMat, binaryMat, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
            Cv2.ImShow("binaryImg", binaryMat);

            //形态学操作
            Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(5, 3), new Point(-1, -1));
            Cv2.MorphologyEx(binaryMat, binaryMat, MorphTypes.Dilate, kernel, new Point(-1, -1), 1);
            Cv2.ImShow("Dilate", binaryMat);

            //距离变换
            Mat dist = new Mat();
            Cv2.BitwiseNot(binaryMat, binaryMat);
            Cv2.ImShow("binaryMat", binaryMat);
            Cv2.DistanceTransform(binaryMat, dist, DistanceTypes.L2, DistanceMaskSize.Mask3);
            Cv2.Normalize(dist, dist, 0, 1, NormTypes.MinMax);
            //Cv2.ImShow("distImage", dist);

            //阈值化二值分割
            Mat dist_8U = new Mat();
            dist.ConvertTo(dist_8U, MatType.CV_8U);
            //自适应阈值则,是根据像素的邻域块的像素值分布来确定该像素位置上的二值化阈值
            Cv2.AdaptiveThreshold(dist_8U, dist_8U, 250, AdaptiveThresholdTypes.GaussianC, ThresholdTypes.Binary, 101, 0);
            Cv2.ImShow("dist-AdaptiveThreshold", dist_8U);
            kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(5, 3), new Point(-1, -1));
            Cv2.Dilate(dist_8U, dist_8U, kernel, new Point(-1, -1), 2);
            Cv2.ImShow("dist-Dilate", dist_8U);

            //连通区域计算
            Point[][] contours;
            HierarchyIndex[] hierarchies;
            Cv2.FindContours(dist_8U, out contours, out hierarchies, RetrievalModes.External, ContourApproximationModes.ApproxSimple);

            //绘制结果图像
            Mat markRet = Mat.Zeros(src.Size(), MatType.CV_8UC3);
            RNG rng = new RNG(12345);
            for (int i = 0; i < contours.Length; i++)
            {
                Cv2.DrawContours(markRet, contours, i, new Scalar(rng.Uniform(0, 255), rng.Uniform(0, 255), rng.Uniform(0, 255)), -1, LineTypes.Link8);
            }
            num = contours.Length;
            return markRet;
        }

 处理后部分图像如下所示:

        二值图像

OpenCv案例(一):OpenCvSharp识别图像中物体个数_第2张图片

         形态学操作(膨胀操作)

OpenCv案例(一):OpenCvSharp识别图像中物体个数_第3张图片

          二值图像

OpenCv案例(一):OpenCvSharp识别图像中物体个数_第4张图片

         自适应阈值后再次形态学操作(膨胀)

OpenCv案例(一):OpenCvSharp识别图像中物体个数_第5张图片

         颜色填充

OpenCv案例(一):OpenCvSharp识别图像中物体个数_第6张图片

        打印结果 

OpenCv案例(一):OpenCvSharp识别图像中物体个数_第7张图片         

 该案例基本处理步骤如上,主要难点是如何分离粘连部分的操作;不同图像需要对上述算法中一些参数进行调整(若不理解部分算法参数含义,查找相关资料学习);

你可能感兴趣的:(OpenCVSharp视觉学习,计算机视觉,opencv,图像处理)