private void yangchen_Click(object sender, EventArgs e)
        {
            var fileName = string.Empty;
            OpenFileDialog openDlg = new OpenFileDialog();
            if (openDlg.ShowDialog() == DialogResult.OK)
            {
                fileName = openDlg.FileName;
            }
            Mat g_midimage = new Mat();
            Mat himg = new Mat();
            Mat simg = new Mat();
            Mat vimg = new Mat();
            Mat tmpimage = new Mat();
            Mat binary_image = new Mat();
            Mat g_srcimage = Cv2.ImRead(fileName);//读图片
            Cv2.CvtColor(g_srcimage, g_midimage, ColorConversionCodes.BGR2HSV);//RGB转HSV

            Mat[] mats = Cv2.Split(g_midimage);//分离HSV三通道,分成三张图片
            himg = mats[0];
            simg = mats[1];
            vimg = mats[2];

            #region 二值化H,S,V图像  
            for (int i = 0; i < himg.Rows; i++)
            {
                for (int j = 0; j < himg.Cols; j++)
                {
                    byte hvalue = himg.At<byte>(i, j);
                    if ((hvalue > 0 && hvalue < 30) || (hvalue > 170 && hvalue < 180))//当H图像像素值在0~30和170~180范围内时,得到为白色否则为黑,下面相同。
                        himg.At<byte>(i, j) = 255;
                    else
                        himg.At<byte>(i, j) = 0;


                }
            }
            for (int i = 0; i < simg.Rows; i++)
            {
                for (int j = 0; j < simg.Cols; j++)
                {
                    byte svalue = simg.At<byte>(i, j);
                    if ((svalue > 0 && svalue < 20) || (svalue > 50 && svalue < 100))
                        simg.At<byte>(i, j) = 255;
                    else
                        simg.At<byte>(i, j) = 0;


                }
            }
            for (int i = 0; i < vimg.Rows; i++)
            {
                for (int j = 0; j < vimg.Cols; j++)
                {
                    byte vvalue = vimg.At<byte>(i, j);
                    if (vvalue > 170 && vvalue < 220)
                        vimg.At<byte>(i, j) = 255;
                    else
                        vimg.At<byte>(i, j) = 0;


                }
            }
            #endregion

            //将三通道合并,最终得到二值化图像binary_image
            Cv2.BitwiseAnd(himg, simg, tmpimage);
            Cv2.BitwiseAnd(tmpimage, vimg, binary_image);
            //Cv2.ImShow("binary", binary_image);

            //腐蚀操作得到前景图片,腐蚀6次
            Mat fg = new Mat();
            Cv2.Erode(binary_image, fg, new Mat(), new Point(-1, -1), 6);

            //显示前景图片
            //Cv2.ImShow("foreground", fg);


            //膨胀操作,膨胀6次
            Mat bg = new Mat(); ;
            Cv2.Dilate(binary_image, bg, new Mat(), new Point(-1, -1), 6);
            //将膨胀的图片阈值化操作,得到背景图片,
            var Scalarscalar = Cv2.Mean(g_midimage);//计算灰度图平均值
            Cv2.Threshold(bg, bg, Scalarscalar.Val2, 128, ThresholdTypes.BinaryInv);
            //显示背景图片
            //Cv2.ImShow("background", bg);
            //将前景和背景图片相加,得到掩膜图片
            //Mat markers(binary_image.size(), CV_8U, Scalar(0));
            Mat markers = new Mat(binary_image.Size(), MatType.CV_8U, new Scalar(0));
            markers = fg + bg;
            //Cv2.ImShow("markers", markers);
            //分水岭函数的掩膜必须是32位的,故将八位图片转化成32位图片,进行分水岭操作,结果存在markers中
            markers.ConvertTo(markers, MatType.CV_32S);
            Cv2.Watershed(g_srcimage, markers);

            //将得到的markers图片转化成八位图片
            Mat tmp = new Mat();
            markers.ConvertTo(tmp, MatType.CV_8U);

            //像素统计,逐行统计,计算白色区域的像素和
            double pixekcount = 0.0, blackcount = 0.0;
            for (int i = 0; i < tmp.Rows; i++)
            {

                for (int j = 0; j < tmp.Cols; j++)
                {
                    pixekcount++;
                    byte gvalue = tmp.At<byte>(i, j);
                    if (gvalue == 255)
                        blackcount++;
                }
            }

            //计算白色区域的比例
            double scale_img;
            scale_img = blackcount / pixekcount;
            //大于0.05则在图上打上有问题的标签
            if (scale_img > 0.05)
            {
                Cv2.PutText(tmp, "have question", new Point(0, 10), HersheyFonts.HersheyComplex, 0.3, new Scalar(255, 0, 0));//打印函数
                Cv2.ImShow("segment", tmp);//显示有问题的图片,按计划这里应该是传图片或者存图片
                //MessageBox.Show("have question");
            }
            else
            {
            }
            //Cv2.ImShow("segment", tmp);//显示最终的图片
            Cv2.WaitKey(0);
        }

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐