//Grabcut分割函数封装
        private Mat grabCut(Mat image, int ITER_COUNT, GrabCutModes GRABCUTMODE, int x, int y, int w, int h)
        {
            var       bgModel   = new Mat();
            var       fgdModel  = new Mat();
            var       bgModel1  = new Mat();
            var       fgdModel1 = new Mat();
            var       mask      = new Mat();
            const int GC_PR_FGD = 3;
            Rect      rect      = new Rect();

            rect.X      = x;
            rect.Y      = y;
            rect.Width  = w;
            rect.Height = h;
            Cv2.GrabCut(image, mask, rect, bgModel, fgdModel, ITER_COUNT, GRABCUTMODE);
            Cv2.Compare(mask, GC_PR_FGD, mask, CmpTypes.EQ);
            Mat foreground = new Mat(image.Size(), MatType.CV_8UC3, new Scalar(0, 0, 0));

            image.CopyTo(foreground, mask);
            showRect(rect.X, rect.Y, rect.Width, rect.Height);
            showImagePara(image);
            return(foreground);
        }
 //更改参数再次分割图片
 private void button4_Click(object sender, EventArgs e)
 {
     if (comboBox1.Text == "grabcut" && value1.Text == "迭代次数:" && value2.Text == "分割算子:")
     {
         try
         {
             int          iter_count  = int.Parse(textBox5.Text);
             GrabCutModes grabcutmode = (GrabCutModes)(Enum.Parse(typeof(GrabCutModes), comboBox4.Text));
             int          x           = int.Parse(textBox7.Text);
             int          y           = int.Parse(textBox8.Text);
             int          w           = int.Parse(textBox9.Text);
             int          h           = int.Parse(textBox10.Text);
             if (iter_count > 20 || iter_count < 0)
             {
                 MessageBox.Show("迭代次数于0-20次之内较为合适");
             }
             else
             {
                 System.Drawing.Bitmap bitmap = (System.Drawing.Bitmap)pictureBox1.Image;
                 Mat    image     = BitmapConverter.ToMat(bitmap);
                 double startTime = Cv2.GetTickCount();
                 Mat    res       = grabCut(image, iter_count, grabcutmode, x, y, w, h);
                 double duration  = (Cv2.GetTickCount() - startTime) / (Cv2.GetTickFrequency());
                 showImage(res, duration);
                 showParameters("迭代次数:", iter_count.ToString(), "分割算子:", grabcutmode.ToString());
                 textBox6.Hide();
                 showRect(x, y, w, h);
             }
         }
         catch (Exception err)
         {
             if (err.ToString().Contains("totalSampleCount"))
             {
                 MessageBox.Show("您选择的区域无法分割出前景,无法分割,请重新选择区域大小");
             }
             else if (err.ToString().Contains("mask"))
             {
                 MessageBox.Show("掩模mask为空,无法分割");
             }
             else if (err.ToString().Contains("Format"))
             {
                 MessageBox.Show("输入的字符串格式不正确,请重新输入");
             }
         }
     }
     if (comboBox1.Text == "watershed" && value1.Text == "中值滤波内核:" && value2.Text == "形态学卷积核:")
     {
         try
         {
             if (int.Parse(textBox5.Text) % 2 == 0)
             {
                 MessageBox.Show("中值滤波内核应为奇数,请重新输入。");
             }
             else
             {
                 int meadianblur_ksize = int.Parse(textBox5.Text);
                 if (meadianblur_ksize > 1000 || meadianblur_ksize < 0)
                 {
                     MessageBox.Show("数值不合理,请重新输入适当的数值");
                 }
                 else
                 {
                     string   text                = textBox6.Text;
                     string   diff11              = text.Replace("(", string.Empty);
                     string   diff12              = diff11.Replace(")", string.Empty);
                     string[] str                 = diff12.Split(',');
                     Size     element_size        = new Size(int.Parse(str[0]), int.Parse(str[1]));
                     System.Drawing.Bitmap bitmap = (System.Drawing.Bitmap)pictureBox1.Image;
                     Mat    image                 = BitmapConverter.ToMat(bitmap);
                     double startTime             = Cv2.GetTickCount();
                     Mat    result                = waterShed(image, meadianblur_ksize, element_size);
                     double duration              = (Cv2.GetTickCount() - startTime) / (Cv2.GetTickFrequency());
                     showImage(result, duration);
                     showParameters("中值滤波内核:", meadianblur_ksize.ToString(), "形态学卷积核:", "(" + element_size.Width.ToString() + "," + element_size.Height.ToString() + ")");
                 }
             }
         }
         catch (Exception err)
         {
             if (err.ToString().Contains("Format"))
             {
                 MessageBox.Show("输入的字符串格式不正确,请重新输入");
             }
             else if (err.ToString().Contains("索引超出了数组界限"))
             {
                 MessageBox.Show("形态学卷积内核应用英文括号隔开");
             }
             else
             {
                 MessageBox.Show(err.ToString());
             }
         }
     }
     if (comboBox1.Text == "meanshift" && value1.Text == "颜色域半径:" && value2.Text == "空间域半径:")
     {
         try
         {
             int meanshift_sp = int.Parse(textBox5.Text);
             int meanshift_sr = int.Parse(textBox6.Text);
             if (meanshift_sp < 0 || meanshift_sr < 0 || meanshift_sp > 1000 || meanshift_sr > 1000)
             {
                 MessageBox.Show("参数有误或数值过大,请重新输入数据");
             }
             else
             {
                 System.Drawing.Bitmap bitmap = (System.Drawing.Bitmap)pictureBox1.Image;
                 Mat    image     = BitmapConverter.ToMat(bitmap);
                 double startTime = Cv2.GetTickCount();
                 Mat    res       = meanShift(image, meanshift_sp, meanshift_sr);
                 double duration  = (Cv2.GetTickCount() - startTime) / (Cv2.GetTickFrequency());
                 showImage(res, duration);
                 showParameters("颜色域半径:", meanshift_sp.ToString(), "空间域半径:", meanshift_sr.ToString());
             }
         }
         catch (Exception err)
         {
             if (err.ToString().Contains("Format"))
             {
                 MessageBox.Show("输入的字符串格式不正确,请重新输入");
             }
             else
             {
                 MessageBox.Show(err.ToString());
             }
         }
     }
     if (comboBox1.Text == "floodfill" && value1.Text == "像素最大下行差异值:" && value2.Text == "像素最大上行差异值:")
     {
         try
         {
             string   diff1  = textBox5.Text;
             string   diff11 = diff1.Replace("[", string.Empty);
             string   diff12 = diff11.Replace("]", string.Empty);
             string[] str1   = diff12.Split(',');
             Scalar   lodiff = new Scalar(int.Parse(str1[0]), int.Parse(str1[1]), int.Parse(str1[2]), int.Parse(str1[3]));
             string   diff2  = textBox6.Text;
             string   diff21 = diff2.Replace("[", string.Empty);
             string   diff22 = diff21.Replace("]", string.Empty);
             string[] str2   = diff22.Split(',');
             int      x      = int.Parse(textBox7.Text);
             int      y      = int.Parse(textBox8.Text);
             int      w      = int.Parse(textBox9.Text);
             int      h      = int.Parse(textBox10.Text);
             Scalar   updiff = new Scalar(int.Parse(str2[0]), int.Parse(str2[1]), int.Parse(str2[2]), int.Parse(str2[3]));
             System.Drawing.Bitmap bitmap = (System.Drawing.Bitmap)pictureBox1.Image;
             Mat    image     = BitmapConverter.ToMat(bitmap);
             double startTime = Cv2.GetTickCount();
             Mat    res       = floodFill(image, lodiff, updiff, x, y, w, h);
             double duration  = (Cv2.GetTickCount() - startTime) / (Cv2.GetTickFrequency());
             showImage(res, duration);
             showRect(x, y, w, h);
             showParameters("像素最大下行差异值:", lodiff.ToString(), "像素最大上行差异值:", updiff.ToString());
         }
         catch (Exception err)
         {
             if (err.ToString().Contains("Format"))
             {
                 MessageBox.Show("输入的字符串格式不正确,请重新输入(应输入英文逗号)");
             }
             else if (err.ToString().Contains("索引超出了数组界限"))
             {
                 MessageBox.Show("像素最大下(上)行差异值应用英文括号隔开");
             }
             else
             {
                 MessageBox.Show(err.ToString());
             }
         }
     }
     if (comboBox1.Text == "contour" && value1.Text == "高斯核x方向标准差:" && value2.Text == "二值化算子:")
     {
         try
         {
             ThresholdTypes        contour_type = (ThresholdTypes)(Enum.Parse(typeof(ThresholdTypes), comboBox4.Text));
             int                   sigmax       = int.Parse(textBox5.Text);
             System.Drawing.Bitmap bitmap       = (System.Drawing.Bitmap)pictureBox1.Image;
             Mat                   image        = BitmapConverter.ToMat(bitmap);
             double                startTime    = Cv2.GetTickCount();
             Mat                   res          = contourSeg(image, contour_type, sigmax);
             double                duration     = (Cv2.GetTickCount() - startTime) / (Cv2.GetTickFrequency());
             showImage(res, duration);
             showParameters("高斯核x方向标准差:", sigmax.ToString(), "二值化算子:", contour_type.ToString());
             textBox6.Hide();
         }
         catch (Exception err)
         {
             if (err.ToString().Contains("Format"))
             {
                 MessageBox.Show("输入的字符串格式不正确,请重新输入");
             }
             else if (err.ToString().Contains("索引超出了数组界限"))
             {
                 MessageBox.Show("索引超出了数组界限,无法分割");
             }
             else
             {
                 MessageBox.Show(err.ToString());
             }
         }
     }
 }
Beispiel #3
0
 /// <summary>
 /// Segments the image using GrabCut algorithm
 /// </summary>
 /// <param name="img">Input 8-bit 3-channel image.</param>
 /// <param name="mask">Input/output 8-bit single-channel mask. 
 /// The mask is initialized by the function when mode is set to GC_INIT_WITH_RECT. 
 /// Its elements may have Cv2.GC_BGD / Cv2.GC_FGD / Cv2.GC_PR_BGD / Cv2.GC_PR_FGD</param>
 /// <param name="rect">ROI containing a segmented object. The pixels outside of the ROI are 
 /// marked as "obvious background". The parameter is only used when mode==GC_INIT_WITH_RECT.</param>
 /// <param name="bgdModel">Temporary array for the background model. Do not modify it while you are processing the same image.</param>
 /// <param name="fgdModel">Temporary arrays for the foreground model. Do not modify it while you are processing the same image.</param>
 /// <param name="iterCount">Number of iterations the algorithm should make before returning the result. 
 /// Note that the result can be refined with further calls with mode==GC_INIT_WITH_MASK or mode==GC_EVAL .</param>
 /// <param name="mode">Operation mode that could be one of GrabCutFlag value.</param>
 public static void GrabCut(InputArray img, InputOutputArray mask, Rect rect,
                            InputOutputArray bgdModel, InputOutputArray fgdModel,
                            int iterCount, GrabCutModes mode)
 {
     if (img == null)
         throw new ArgumentNullException(nameof(img));
     if (mask == null)
         throw new ArgumentNullException(nameof(mask));
     if (bgdModel == null)
         throw new ArgumentNullException(nameof(bgdModel));
     if (fgdModel == null)
         throw new ArgumentNullException(nameof(fgdModel));
     img.ThrowIfDisposed();
     mask.ThrowIfNotReady();
     bgdModel.ThrowIfNotReady();
     fgdModel.ThrowIfNotReady();
     NativeMethods.imgproc_grabCut(img.CvPtr, mask.CvPtr, rect,
         bgdModel.CvPtr, fgdModel.CvPtr, iterCount, (int)mode);
     GC.KeepAlive(img);
     mask.Fix();
     bgdModel.Fix();
     fgdModel.Fix();
 }
Beispiel #4
0
 /// <summary>
 /// Segments the image using GrabCut algorithm.
 /// The input is 8-bit 3-channel image.
 /// </summary>
 /// <param name="mask">Input/output 8-bit single-channel mask. 
 /// The mask is initialized by the function when mode is set to GC_INIT_WITH_RECT. 
 /// Its elements may have Cv2.GC_BGD / Cv2.GC_FGD / Cv2.GC_PR_BGD / Cv2.GC_PR_FGD</param>
 /// <param name="rect">ROI containing a segmented object. The pixels outside of the ROI are 
 /// marked as "obvious background". The parameter is only used when mode==GC_INIT_WITH_RECT.</param>
 /// <param name="bgdModel">Temporary array for the background model. Do not modify it while you are processing the same image.</param>
 /// <param name="fgdModel">Temporary arrays for the foreground model. Do not modify it while you are processing the same image.</param>
 /// <param name="iterCount">Number of iterations the algorithm should make before returning the result. 
 /// Note that the result can be refined with further calls with mode==GC_INIT_WITH_MASK or mode==GC_EVAL .</param>
 /// <param name="mode">Operation mode that could be one of GrabCutFlag value.</param>
 public void GrabCut(InputOutputArray mask, Rect rect,
     InputOutputArray bgdModel, InputOutputArray fgdModel,
     int iterCount, GrabCutModes mode)
 {
     Cv2.GrabCut(this, mask, rect, bgdModel, fgdModel, iterCount, mode);
 }