美文网首页
C#:用OpenCV实现缺陷检测

C#:用OpenCV实现缺陷检测

作者: 大龙10 | 来源:发表于2023-02-17 11:41 被阅读0次

    一、简介

    • 机器视觉应用场景中缺陷检测的应用是非常广泛的,通常涉及各个行业、各种缺陷类型。
    • 纺织物的缺陷检测,缺陷类型包含脏污、油渍、线条破损三种,这三种缺陷与LCD屏幕检测的缺陷很相似,处理方法也可借鉴。
    • 使用OpenCV中的FindContours函数可以 实现纺织物缺陷检测(脏污、油渍、线条破损缺陷)。

    二、FindContours函数

    • FindContours函数
      找轮廓
    void findContours( InputOutputArray image, 
          OutputArrayOfArrays contours,
          OutputArray hierarchy, int mode,
          int method, Point offset = Point());
    
    • InputOutputArray image:输入图像是8位单通道的图像(256级灰度图)。
      其中像素点的非0灰度值被当成1(转化后即为255),0值保持0,所以输入图像被当成一个二值图像对待。
      可以用 compare() , inRange() , threshold() , adaptiveThreshold() , Canny() 或者其他方法来从灰度图或者彩色图中生成二值图像。该函数在提取轮廓的过程中会改变图像
      如果第4个参数 mode 为 CV_RETR_CCOMP 或者
      CV_RETR_FLOODFILL,输入图像也可以是32位的整型图像(CV_32SC1)。

    • OutputArrayOfArrays contours: 检测到的轮廓
      Each contour is stored as a vector of points. 每个轮廓会被存储为vector<Point>
      所以 contours 的类型是vector<vector<Point>>

    • OutputArray hierarchy: 可选的输出向量,包含图像的拓扑信息
      It has as many elements as the number of contours. 元素个数 = 轮廓数
      对于第 i 个轮廓contours[i],hierarchy 的以下元素分别表示
      hierarchy[i][0]: the next contour at the same hierarchical level
      hierarchy[i][1]: the previous contour at the same hierarchical level
      hierarchy[i][2]: the first child contour
      hierarchy[i][3]: the parent contour
      hierarchy 的这些元素的原始值为0,如果不存在,置为负数

    • int mode: Contour retrieval mode 取回轮廓模式(复杂度依次增加)

    三、检测条件

    先进行二值化、高斯滤波、平滑等处理。再进行轮廓分析。

    • 脏污
      轮廓圆弧长度大于1
    • 油渍
      轮廓面积大于50
    • 线条破损
      轮廓圆弧长度大于10


      脏污检测

    四、程序源码

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using Sunny.UI;
    using OpenCvSharp;
    using OpenCvSharp.Extensions;
    
    namespace Ky_FindContours
    {
        public partial class Form1 : UIForm
        {
            public Form1()
            {
                InitializeComponent();
                this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true);
    
            }
            private Image image = null;
            private Mat dst = new Mat();
            private Mat src_img;
            string filePath = "";
            private List<Mat> reList = new List<Mat>();
            private int step = 1;
    
            private void openImage_Click(object sender, EventArgs e)
            {
                OpenFileDialog openFileDialog = new OpenFileDialog();
                openFileDialog.Title = "选择操作的图片";
                openFileDialog.Filter = "图片 *.jpg|*.jpg|图像*.png|*.png";
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    filePath = openFileDialog.FileName;
                    image = Image.FromFile(filePath);
                    src_img = Cv2.ImRead(filePath);
                    Mat tem1 = new Mat();
                    src_img.CopyTo(tem1);
                    if (reList.Count > 0)
                    {
                        reList[0] = tem1;
    
                    }
                    else
                    {
                        reList.Add(tem1);
                    }
    
                }
                if (filePath != "")
                {
                    picBoxShowDel.Image = image;
                    picShowOri.Image = image;
                }
    
            }
    
            /// <summary>
            /// 脏污缺陷检测
            /// </summary>
            /// <param name="img">测试图像</param>
            /// <returns>结果图</returns> //也可设置bool类型表示OK或NG
            static Mat DirtyDetection(Mat img)
            {
                Mat result = img.Clone();
                Mat gray = new Mat();
                Cv2.CvtColor(img, gray, ColorConversionCodes.BGR2GRAY);
                Cv2.GaussianBlur(gray, gray, new OpenCvSharp.Size(7, 7), 0);
                Cv2.Canny(gray, gray, 10, 30);
                OpenCvSharp.Point[][] contours; //轮廓查找结果变量
                HierarchyIndex[] hierarchy; //轮廓拓扑结构变量
    
                Cv2.FindContours(gray, out contours, out hierarchy, RetrievalModes.External,
                                ContourApproximationModes.ApproxNone);
                //Console.WriteLine("contour_size = {0}", contours.Length); //输出轮廓个数
    
                for (int i = 0; i < contours.Length; i++)
                {
                    double length = Cv2.ArcLength(contours[i], true);
                    if (length >= 1)
                        Cv2.DrawContours(result, contours, i, new Scalar(0, 0, 255), 2);
                }
                return result;
            }
    
            /// <summary>
            /// 油污缺陷检测
            /// </summary>
            /// <param name="img">测试图像</param>
            /// <returns>结果图</returns> //也可设置bool类型表示OK或NG
            static Mat OilDetection(Mat img)
            {
                Mat result = img.Clone();
                Mat imgLab = new Mat();
                Cv2.CvtColor(img, imgLab, ColorConversionCodes.BGR2Lab);
                Mat[] labArray = Cv2.Split(imgLab); //L, a, b
                Mat blur = new Mat();
                Mat thres = new Mat();
                Cv2.GaussianBlur(labArray[2], blur, new OpenCvSharp.Size(3, 3), 0); //b通道
                Cv2.Threshold(blur, thres, 130, 255, ThresholdTypes.Binary);
                Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3), new OpenCvSharp.Point(-1, -1));
                Cv2.MorphologyEx(thres, thres, MorphTypes.Open, element, new OpenCvSharp.Point(-1, -1), 1,
                                 BorderTypes.Default, new Scalar());
    
                OpenCvSharp.Point[][] contours; //轮廓查找结果变量
                HierarchyIndex[] hierarchy; //轮廓拓扑结构变量
    
                Cv2.FindContours(thres, out contours, out hierarchy, RetrievalModes.External,
                                ContourApproximationModes.ApproxNone);
                //Console.WriteLine("contour_size = {0}", contours.Length); //输出轮廓个数
    
                for (int i = 0; i < contours.Length; i++)
                {
                    double area = Cv2.ContourArea(contours[i]);
                    if (area >= 50)
                        Cv2.DrawContours(result, contours, i, new Scalar(0, 0, 255), 2);
                }
                return result;
            }
    
            /// <summary>
            /// 线条破损缺陷检测
            /// </summary>
            /// <param name="img">测试图像</param>
            /// <returns>结果图</returns> //也可设置bool类型表示OK或NG
            static Mat LineDefectDetection(Mat img)
            {
                Mat result = img.Clone();
                Mat imgLab = new Mat();
                Cv2.CvtColor(img, imgLab, ColorConversionCodes.BGR2Lab);
                Mat[] labArray = Cv2.Split(imgLab); //L, a, b
                Mat blur = new Mat();
                Mat edged = new Mat();
                Cv2.GaussianBlur(labArray[2], blur, new OpenCvSharp.Size(3, 3), 0); //b通道
                Cv2.Canny(blur, edged, 5, 10);
                OpenCvSharp.Point[][] contours; //轮廓查找结果变量
                HierarchyIndex[] hierarchy; //轮廓拓扑结构变量
    
                Cv2.FindContours(edged, out contours, out hierarchy, RetrievalModes.External,
                                ContourApproximationModes.ApproxNone);
                //Console.WriteLine("contour_size = {0}", contours.Length); //输出轮廓个数
    
                for (int i = 0; i < contours.Length; i++)
                {
                    double length = Cv2.ArcLength(contours[i], true);
                    if (length >= 10)
                        Cv2.DrawContours(result, contours, i, new Scalar(0, 0, 255), 2);
                }
                return result;
            }
    
            private void uiButton1_Click(object sender, EventArgs e)
            {
                Mat zw_result = DirtyDetection(src_img); //脏污缺陷检测
                picBoxShowDel.Image = zw_result.ToBitmap();
            }
    
            private void uiButton2_Click(object sender, EventArgs e)
            {
                Mat yw_result = OilDetection(src_img); //油污缺陷检测
                picBoxShowDel.Image = yw_result.ToBitmap();
            }
    
            private void uiButton3_Click(object sender, EventArgs e)
            {
                Mat yw_result = LineDefectDetection(src_img); //线条破损缺陷检测
                picBoxShowDel.Image = yw_result.ToBitmap();
            }
        }
    }
    
    
    油污检测

    五、参考资料

    博客:https://blog.51cto.com/stq054188/5543992
    来源公众号:OpenCV与AI深度学习
    

    相关文章

      网友评论

          本文标题:C#:用OpenCV实现缺陷检测

          本文链接:https://www.haomeiwen.com/subject/pfbmkdtx.html