美文网首页
C#:颜色识别

C#:颜色识别

作者: 大龙10 | 来源:发表于2023-12-14 12:53 被阅读0次

一、原理

  • 根据提取的颜色HSV模板值做颜色识别
    颜色提取的一种方式是将BGR空间下的图像转换为HSV空间下,然后利用opencv自带函数inRange,设置需提取的HSV各分量上下限,从而进行提取。
  • 下面给出HSV对应BGR颜色的表格


二、InRange函数

inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded);

  • 这个函数的作用就是检测src图像的每一个像素是不是在lowerb和upperb之间,如果是,这个像素就设置为255,并保存在dst图像中,否则为0。

三、程序

       private void button2_Click_1(object sender, EventArgs e)
        {
            // 黄色的HSV区间。也可换成上面提取的HSV颜色模板来识别颜色
            int low_H = 26;
            int high_H = 34;
            int low_S = 43;
            int high_S = 255;
            int low_V = 46;
            int high_V = 255;

            Mat hsv_image = new Mat(); 
            Cv2.CvtColor(src_img, hsv_image, ColorConversionCodes.BGR2HSV);
            //因为我们读取的是彩色图,直方图均衡化需要在HSV空间做
            Mat[] hsvSplit;
            hsvSplit=Cv2.Split(hsv_image);
            Cv2.EqualizeHist(hsvSplit[2], hsvSplit[2]);
            Cv2.Merge(hsvSplit, hsv_image);

            Mat imgThresholded = new Mat();
            Cv2.InRange(hsv_image, new Scalar(low_H, low_S, low_V), new Scalar(high_H, high_S, high_V), imgThresholded);

            //开操作 (去除一些噪点)
            Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5) );
            Cv2.MorphologyEx(imgThresholded, imgThresholded, MorphTypes.Open, element);

            //闭操作 (连接一些连通域)
            Cv2.MorphologyEx(imgThresholded, imgThresholded, MorphTypes.Close, element);
            Cv2.ImShow("imgThresholded", imgThresholded);

            //  轮廓最小外接矩形的绘制 和 粗略计算物体像素长宽
            OpenCvSharp.Point[][] contours;
            HierarchyIndex[] hierarchies;
            //  1.2查找轮廓
            Cv2.FindContours(imgThresholded, out contours, out hierarchies, RetrievalModes.External, ContourApproximationModes.ApproxSimple, new OpenCvSharp.Point());
            //排序
            //SortContourPoint(contours, contours, 0, true);
            //1.3绘制所有轮廓  
            dst = src_img.Clone();
            Cv2.DrawContours(dst, contours, -1, new Scalar(0, 0, 255), 1, LineTypes.Link8, hierarchies);

            //2.由轮廓确定正外接矩形及最小外接矩形 
            //2.1 定义Rect类型的vector容器boundRect存放正外接矩形,初始化大小为contours.Length)即轮廓个数  
            Rect[] boundRect = new Rect[contours.Length];
            //2.2 定义Rect类型的vector容器roRect存放最小外接矩形,初始化大小为contours.Length)即轮廓个数  
            RotatedRect[] roRect = new RotatedRect[contours.Length];
            //2.3 遍历每个轮廓

            for (int i = 0; i < contours.Length; i++)
            {
                //2.4 由轮廓(点集)确定出正外接矩形并绘制
                boundRect[i] = Cv2.BoundingRect(contours[i]);

                //2.4.1获得正外接矩形的左上角坐标及宽高  
                int width = boundRect[i].Width;
                int height = boundRect[i].Height;
                int x = boundRect[i].X;
                int y = boundRect[i].Y;
                //2.4.2用画矩形方法绘制正外接矩形
                Cv2.Rectangle(dst, boundRect[i], new Scalar(255, 0, 0), 2, LineTypes.Link8, 0);

                //2.5 由轮廓(点集)确定出最小外接矩形并绘制
                //旋转矩形主要成员有center、size、 angle、points()
                roRect[i] = Cv2.MinAreaRect(contours[i]);
                //2.5.1 旋转矩形类RotatedRect中有Point()方法,参数Point2f* pts,将旋转矩形的四个端点存储进pts.

                Point2f[] pts = roRect[i].Points();    //把最小外接矩形四个端点复制给pts数组
                //2.5.2 用line方法,根据旋转矩形的四个角点画出最小外接矩形每条边
                for (int j = 0; j < 4; j++)
                { 
                    Cv2.Line(dst,(int)pts[j].X, (int)pts[j].Y, (int)pts[(j+1)%4].X, (int)pts[(j + 1) % 4].Y, new Scalar(0, 0, 255), 2, LineTypes.Link8, 0); 
                }
                //*2.5.3 由旋转矩形的center成员得出中心点
                Point2f center = roRect[i].Center;
                //*2.5.4 用circle方法画出中心点center
                Cv2.Circle(dst,(int) center.X, (int)center.Y, 5, new Scalar(0, 255, 0), -1, LineTypes.Link8,0);
                //*2.5.5 由旋转矩形的size成员得出宽和高

                double widthRotated = roRect[i].Size.Width;
                double heightRotated = roRect[i].Size.Height;
                Cv2.PutText(dst, "W:" + widthRotated.ToString(""), new OpenCvSharp.Point(20 , 40 + i * 100), HersheyFonts.HersheySimplex, 1, new Scalar(255, 0, 0), 1, LineTypes.Link8);
                Cv2.PutText(dst, "H:" + heightRotated.ToString(""), new OpenCvSharp.Point(20, 60 + i * 100), HersheyFonts.HersheySimplex, 1, new Scalar(255, 0, 0), 1, LineTypes.Link8);
                Cv2.PutText(dst, "NO:" + i.ToString(""), new OpenCvSharp.Point(20, 20+ i * 100), HersheyFonts.HersheySimplex, 1, new Scalar(255, 0, 0), 1, LineTypes.Link8);
            }
            Cv2.ImShow("粗略计算物体像素长宽", dst);
        }
    }

四、运行结果

运行结果

五、资料

c1learning的博客:
https://blog.csdn.net/c1learning/article/details/100130805

相关文章

网友评论

      本文标题:C#:颜色识别

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