C# OpenCV高斯模糊,转为HSV格式,颜色过滤,做按位与运算,二值化,灰度图,最小方框,判断是否在多边形内

该博客主要介绍了如何使用Python和C#结合OpenCV进行图像处理,包括高斯模糊、颜色转换、颜色过滤、边界查找、最小外接矩形等步骤,以实现目标检测。作者强调在C#中寻找相应函数的困难,并分享了通过查看C++源代码解决问题的经验。
摘要由CSDN通过智能技术生成

还未有时间做注解,代码里面基本有简单的注解。

使用Python、C++写OpenCV不难,使用C#则很多语法找不到,本文里面很多函数的使用,都是查看C++源代码,花费很多时间才写出来的

  public static OpenCvSharp.Mat Detection(Mat src0, string[] Para, out int Count
            , out string OutInfo, OpenCvSharp.Point[][] RectCnts, Mat SrcOriginalDraw
            , out Mat SrcOriginal, bool BoxCorn) //传入目标参数
        {
            OutInfo = "";

            Mat src = src0;
            Mat src2 = src0;

            SrcOriginal = src0;

            Mat dst = new Mat();
            Cv2.GaussianBlur(src, dst, new OpenCvSharp.Size(5, 5), 0);//高斯模糊
            //Cv2.MedianBlur(src,dst,5);

            //处理反光
            //Mat illum = new Mat();
            //Mat illumMask = new Mat(Environment.CurrentDirectory+ "\\BlackMask2.jpg", ImreadModes.Color);
            //illumMask = Mat.Zeros(illumMask.Size(),OpenCvSharp.MatType.CV_8UC1);
            //Cv2.IlluminationChange(dst,illumMask,illum,0.2f,0.4f);

            //转位HSV格式
            var HSV = new Mat();
            Cv2.CvtColor(dst, HSV, ColorConversionCodes.BGR2HSV);

            //颜色过滤
            var Mask = new Mat();
            Cv2.InRange(HSV, new Scalar(int.Parse(Para[0]), int.Parse(Para[1]), int.Parse(Para[2]))
                , new Scalar(int.Parse(Para[3]), int.Parse(Para[4]), int.Parse(Para[5])), Mask);

            //做按位与运算
            Mat Things = new Mat();
            Cv2.BitwiseAnd(src, src, Things, Mask);

            //二值化
            Mat ErodeHSV = new Mat();
            Cv2.Erode(Things, ErodeHSV, null, null, int.Parse(Para[6]));

            //灰度图
            Mat ThingsGray = new Mat();
            OpenCvSharp.HierarchyIndex[] cnts = null;
            OpenCvSharp.Point[][] cntsArray = null;
            Cv2.CvtColor(ErodeHSV, ThingsGray, ColorConversionCodes.RGB2GRAY);
            //查找边界
            Cv2.FindContours(ThingsGray, out cntsArray, out cnts, RetrievalModes.External
                , ContourApproximationModes.ApproxSimple);

            int MaxBox = -1;
            double MaxBoxArea = 0;
            for (int i = 0; i < RectCnts.Length; i++)
            {
                if (Cv2.ContourArea(RectCnts[i]) > MaxBoxArea)
                {
                    MaxBoxArea = Cv2.ContourArea(RectCnts[i]);
                    MaxBox = i;
                }
            }

            OpenCvSharp.RotatedRect[] Box = new RotatedRect[cntsArray.Length];
            //OpenCvSharp.CircleSegment[] Cir = new OpenCvSharp.CircleSegment[cntsArray.Length];

            //Cv2.DrawContours(src2, cntsArray, -1, new Scalar(0, 255, 0), 9);

            //double SumArea = 0;
            Count = 0;
            //Point2f center2f;
            //float radius;
            //OpenCvSharp.Point center;
            //int MaxIndex = 0, SecondIndex = 0;
            string Feature = "";
            OpenCvSharp.Point BoxCenter;
            for (int i = 0; i < cntsArray.Length; i++)
            {
                //在这里画方框 最小方框
                Box[i] = Cv2.MinAreaRect(cntsArray[i]);
                //Cv2.MinEnclosingCircle(cntsArray[i], out center2f, out radius);
                //center.X = int.Parse(Math.Round(center2f.X, 0).ToString());
                //center.Y = int.Parse(Math.Round(center2f.Y, 0).ToString());
                //OpenCvSharp.Point2f[] Vertex = new OpenCvSharp.Point2f[4];
                var Vertex = Box[i].Points();
                if (BoxCorn == false)//为true的时候,四个点必须在盒子里
                {
                    if (Box[i].Size.Height * Box[i].Size.Width > double.Parse(Para[7])     //Cv2.ContourArea(cntsArray[i]) > double.Parse(Threshold.Text) 改为用圆面积判断阈值 3.14 * radius * radius
                        && Box[i].Size.Height * Box[i].Size.Width < double.Parse(Para[8])
                        && (Box[i].Size.Height >= Box[i].Size.Width ? Box[i].Size.Height : Box[i].Size.Width) > double.Parse(Para[9]) //长边范围       
                        && (Box[i].Size.Height >= Box[i].Size.Width ? Box[i].Size.Height : Box[i].Size.Width) < double.Parse(Para[10])
                        && (Box[i].Size.Height >= Box[i].Size.Width ? Box[i].Size.Width : Box[i].Size.Height) > double.Parse(Para[11]) //短边范围        
                        && (Box[i].Size.Height >= Box[i].Size.Width ? Box[i].Size.Width : Box[i].Size.Height) < double.Parse(Para[12])
                        && Cv2.PointPolygonTest(RectCnts[MaxBox], Box[i].Center, false) == 1 //是否在多边形范围内
                    )
                    {
                        Count = Count + 1;

                        //Cv2.Circle(src2,center, int.Parse(Math.Round(radius,0).ToString()), new Scalar(0, 255, 0), 9);

                        Feature = "Feature" + Count.ToString() + ":"
                            + (Box[i].Size.Height * Box[i].Size.Width).ToString("0") + ";"
                            + Box[i].Size.Height.ToString("0") + ";"
                            + Box[i].Size.Width.ToString("0");

                        OutInfo = OutInfo + Feature + "\n";

                        OpenCvSharp.Point2f[] Vector3 = new OpenCvSharp.Point2f[4];
                        Vector3 = Box[i].Points();

                        OpenCvSharp.Point[][] Vector31 = new OpenCvSharp.Point[1][];
                        Vector31[0] = new OpenCvSharp.Point[4];

                        for (int j = 0; j < Vector3.Length; j++)
                        {
                            Vector31[0][j].X = int.Parse(Math.Round(Vector3[j].X, 0).ToString());
                            Vector31[0][j].Y = int.Parse(Math.Round(Vector3[j].Y, 0).ToString());
                        }
                        Cv2.DrawContours(src2, Vector31, -1, new Scalar(0, 255, 0), 9);
                        Cv2.FillPoly(src2, Vector31, new Scalar(0, 255, 0));//填充矩形

                        //Cv2.DrawContours(SrcOriginalDraw, Vector31, -1, new Scalar(0, 255, 255), 9);

                        //打特征值
                        OpenCvSharp.HersheyFonts font = new HersheyFonts();
                        BoxCenter.X = int.Parse(Math.Round(Box[i].Center.X, 0).ToString());
                        BoxCenter.Y = int.Parse(Math.Round(Box[i].Center.Y, 0).ToString());
                        Cv2.PutText(SrcOriginalDraw, Feature, BoxCenter, font, 1, new Scalar(0, 0, 255), 2);

                    }
                }
                else
                {
                    if (Box[i].Size.Height * Box[i].Size.Width > double.Parse(Para[7])     //Cv2.ContourArea(cntsArray[i]) > double.Parse(Threshold.Text) 改为用圆面积判断阈值 3.14 * radius * radius
                        && Box[i].Size.Height * Box[i].Size.Width < double.Parse(Para[8])
                        && (Box[i].Size.Height >= Box[i].Size.Width ? Box[i].Size.Height : Box[i].Size.Width) > double.Parse(Para[9]) //长边范围       
                        && (Box[i].Size.Height >= Box[i].Size.Width ? Box[i].Size.Height : Box[i].Size.Width) < double.Parse(Para[10])
                        && (Box[i].Size.Height >= Box[i].Size.Width ? Box[i].Size.Width : Box[i].Size.Height) > double.Parse(Para[11]) //短边范围        
                        && (Box[i].Size.Height >= Box[i].Size.Width ? Box[i].Size.Width : Box[i].Size.Height) < double.Parse(Para[12])
                        && Cv2.PointPolygonTest(RectCnts[MaxBox], Box[i].Center, false) == 1 //判断是否在多边形内
                        && Cv2.PointPolygonTest(RectCnts[MaxBox], Vertex[0], false) == 1 //四个顶点
                        && Cv2.PointPolygonTest(RectCnts[MaxBox], Vertex[1], false) == 1 
                        && Cv2.PointPolygonTest(RectCnts[MaxBox], Vertex[2], false) == 1
                        && Cv2.PointPolygonTest(RectCnts[MaxBox], Vertex[3], false) == 1
                    )
                    {
                        Count = Count + 1;

                        //Cv2.Circle(src2,center, int.Parse(Math.Round(radius,0).ToString()), new Scalar(0, 255, 0), 9);

                        Feature = "Feature" + Count.ToString() + ":"
                            + (Box[i].Size.Height * Box[i].Size.Width).ToString("0") + ";"
                            + Box[i].Size.Height.ToString("0") + ";"
                            + Box[i].Size.Width.ToString("0");

                        OutInfo = OutInfo + Feature + "\n";

                        OpenCvSharp.Point2f[] Vector3 = new OpenCvSharp.Point2f[4];
                        Vector3 = Box[i].Points();

                        OpenCvSharp.Point[][] Vector31 = new OpenCvSharp.Point[1][];
                        Vector31[0] = new OpenCvSharp.Point[4];

                        for (int j = 0; j < Vector3.Length; j++)
                        {
                            Vector31[0][j].X = int.Parse(Math.Round(Vector3[j].X, 0).ToString());
                            Vector31[0][j].Y = int.Parse(Math.Round(Vector3[j].Y, 0).ToString());
                        }
                        Cv2.DrawContours(src2, Vector31, -1, new Scalar(0, 255, 0), 9);
                        Cv2.FillPoly(src2, Vector31, new Scalar(0, 255, 0));//填充矩形

                        //Cv2.DrawContours(SrcOriginalDraw, Vector31, -1, new Scalar(0, 255, 255), 9);
                        //打特征值
                        OpenCvSharp.HersheyFonts font = new HersheyFonts();
                        BoxCenter.X = int.Parse(Math.Round(Box[i].Center.X, 0).ToString());
                        BoxCenter.Y = int.Parse(Math.Round(Box[i].Center.Y, 0).ToString());
                        //在图片上写字,打标记
                        Cv2.PutText(SrcOriginalDraw, Feature, BoxCenter, font, 1, new Scalar(0, 0, 255), 2);

                    }
                }
            }

            SrcOriginal = SrcOriginalDraw;
            return src2;
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值