OpenCv案例(六):基于OpenCvSharp工业零件缺陷检测

1:需求:某工厂自动化流水线上,检测工站对零件涂胶的工艺是否正常;

2:先看原图,如下所示:

3:需要对图中白色涂胶部分进行检测,检测涂胶是否有断开现象,若有,则为NG,涂胶不合格。(下图箭头指示部分,即是涂胶)

 

 4:处理中几个过程图像如下所示:

        模糊处理-降噪

        图像二值化 

        轮廓提取 

 

         上图可以看出,涂胶没有断开,为合格件。

 5:代码部分如下

public bool ImgProcess(Mat src)
        {
            bool result = false;
            //图像灰度
            Mat matGray = new Mat();
            Cv2.CvtColor(src, matGray, ColorConversionCodes.BGR2GRAY);
            Cv2.ImShow("matGray", matGray);

            Mat BlurMat = new Mat();
            Cv2.MedianBlur(matGray, BlurMat, 5);
            //Cv2.GaussianBlur(matGray, BlurMat, new Size(3, 3), 15, 0, BorderTypes.Default);
            //Cv2.ImShow("MedianBlur", BlurMat);
            //Cv2.Blur(matGray, BlurMat,new Size(5,5));
            Mat bilateralFilter = new Mat();
            Cv2.BilateralFilter(BlurMat, bilateralFilter, 9, 25, 25);

            Mat BlurMat1 = new Mat();
            Cv2.FastNlMeansDenoising(bilateralFilter, BlurMat1, 9);
            Cv2.ImShow("BlurMat1", BlurMat1);


            //binaryImage
            Mat binaryImg = new Mat();
            Cv2.Threshold(BlurMat1, binaryImg, 210, 255, ThresholdTypes.Binary);
            Cv2.ImShow("binary", binaryImg);


            Mat morhpImage = new Mat();
            Mat kernel = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(3,3), new Point(-1, -1));
            开操作 先腐蚀 后膨胀
            Cv2.MorphologyEx(binaryImg, morhpImage, MorphTypes.Erode, kernel, new Point(-1, -1),1);
            Cv2.ImShow("Open", morhpImage);


            Mat laplanceMat = new Mat();
            Cv2.Laplacian(morhpImage, laplanceMat, MatType.CV_8UC1, 3, 3, 5);
            Cv2.ImShow("Laplacian", laplanceMat);



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

            //绘制结果图像
            Mat markRet = Mat.Zeros(src.Size(), MatType.CV_8UC3);
            RNG rng = new RNG(12345);
            double maxArea = 0;
            int index = -1;
            for (int i = 0; i < contours.Length; i++)
            {
                //面积过滤
                double area = Cv2.ContourArea(contours[i]);
                double length = Cv2.ArcLength(contours[i], false);
                if (area > maxArea)
                {
                    maxArea = area;
                    index = i;
                }
                if (length > 500 && length < 1000)
                {
                    Cv2.DrawContours(markRet, contours, i, new Scalar(rng.Uniform(0, 255), rng.Uniform(0, 255), rng.Uniform(0, 255)), 6, LineTypes.Link4);
                }
            }

            Cv2.ImShow("dist-Binary", markRet);
            return result;
        }

 6:以上是对该操作的介绍,若对其中某些算法不明白,可以关键字搜索其算法原理,对其进行调参,这里不做过多介绍。补充一点,上述方法,可适当调节参数,可扩大该方法通用性,欢迎各位伙伴补充交流;

猜你喜欢

转载自blog.csdn.net/qq_37835727/article/details/125789686