品牌网站设计提案,百家号优化,wordpress uk,望牛墩网站建设版权声明#xff1a;本文为博主原创文章#xff0c;转载请在显著位置标明本文出处以及作者网名#xff0c;未经作者允许不得用于商业目的。
本文的VB版本请访问#xff1a;图像分割-Grabcut法-CSDN博客
GrabCut是一种基于图像分割的技术#xff0c;它可以用于将图像中的…版权声明本文为博主原创文章转载请在显著位置标明本文出处以及作者网名未经作者允许不得用于商业目的。
本文的VB版本请访问图像分割-Grabcut法-CSDN博客
GrabCut是一种基于图像分割的技术它可以用于将图像中的前景和背景分离。在实现中GrabCut算法通常需要使用高斯混合模型(GMM)来建立前景和背景的概率分布以便更好的估计像素的标签。同时还需要考虑如何处理边界处的像素以避免边界处的像素被错误地分类。GrabCut算法在图像分割中有着广泛的应用例如人像分割、物体抠图等。
EmguCV使用CvInvoke.GrabCut方法来执行GrabCut算法该方法声明如下
public static void GrabCut( IInputArray img, IInputOutputArray mask, Rectangle rect, IInputOutputArray bgdModel, IInputOutputArray fgdModel, int iterCount, GrabcutInitType type
)
参数说明
img输入输出的图像必须是三通道彩色图像。mask指定的掩码图像必须是单通道灰度图像并且与输入图像具有相同的尺寸。可以传入0-3的值分别为0表示明显为背景的像素、1表示冥相位前景的像素、2表示可能为背景的像素、3表示可能为前景的像素。rect指定的矩形框用于定位大概率可能为前景目标的位置。bgdModel背景模型必须是单通道浮点型Mat。fgdModel前景模型必须是单通道浮点型Mat。iterCount迭代次数用于控制算法的收敛性。typeGrabCut算法初始化类型可以选择GrabCutInitType.WithRect或GrabCutInitType.WithMask分别表示根据提供的矩形初始化或根据掩码初始化。
该方法没有返回值而是直接在mask图像上进行前景分割操作最终获得的mask包含0-3的值含义如参数中说明。 //Grabcut法 private void Button5_Click(object sender, EventArgs e){Mat m new Mat(C:\\learnEmgucv\\tower.jpg, ImreadModes.AnyColor);Mat result new Mat();Mat bg new Mat();Mat fg new Mat();Rectangle rect new Rectangle(80, 30, 680, 450);CvInvoke.GrabCut(m, result, rect, bg, fg, 1, GrabcutInitType.InitWithRect);//输出的result只有4个值//0确定背景//1确定前景//2可能背景//3可能前景//演示框选范围CvInvoke.Rectangle(m, rect, new MCvScalar(255, 255, 255), 1);ImageBox1.Image m;//标记区域Matrixbyte matr new Matrixbyte(result.Rows, result.Cols);result.CopyTo(matr);for (int i 0; i matr.Cols; i){for (int j 0; j matr.Rows; j){//将确定背景和可能背景标记为0否则为255if (matr[j, i] 0 || matr[j, i] 2)matr[j, i] 0;elsematr[j, i] 255;}}Mat midm new Mat();midm matr.Mat;//显示标记的图像CvInvoke.Imshow(midm, midm);//灰度转为彩色Mat midm1 new Mat();CvInvoke.CvtColor(midm, midm1, ColorConversion.Gray2Bgr);Mat mout new Mat();//And运算CvInvoke.BitwiseAnd(m, midm1, mout);CvInvoke.Imshow(mout, mout);}输出结果如下图所示 图8-5 Grabcut法分离前景 //Grabcut法 private void Button6_Click(object sender, EventArgs e){Mat m CvInvoke.Imread(C:\\learnEmgucv\\tower.jpg, ImreadModes.Color);Mat result new Mat();Mat bg new Mat();Mat fg new Mat();Rectangle rect new Rectangle(80, 30, 680, 450);CvInvoke.GrabCut(m, result, rect, bg, fg, 5, GrabcutInitType.InitWithRect);ImageBgr, byte src m.ToImageBgr, byte();ImageBgr, byte dst new ImageBgr, byte(new Size(src.Width, src.Height));ImageGray, byte mask result.ToImageGray, byte();//直接操作Image像素点for (int i 0; i src.Rows; i){for (int j 0; j src.Cols; j){//如果是确定前景和可能前景直接保留原像素点颜色否则为黑色if (mask.Data[i, j, 0] 1 || mask.Data[i, j, 0] 3){dst.Data[i, j, 0] src.Data[i, j, 0];dst.Data[i, j, 1] src.Data[i, j, 1];dst.Data[i, j, 2] src.Data[i, j, 2];}else{dst.Data[i, j, 0] 0;dst.Data[i, j, 1] 0;dst.Data[i, j, 2] 0;}}}ImageBox1.Image dst;}输出结果如下图所示 图8-6 Grabcut法分离前景 //标记为确定前景这里使用InitWithMask 参数private void Button7_Click(object sender, EventArgs e){Mat m new Mat(c:\\learnEmgucv\\lena.jpg, ImreadModes.AnyColor);Mat mask new Mat();Mat bg new Mat();Mat fg new Mat();Rectangle rect new Rectangle(80, 30, 340, 480);//使用前景为全白色Mat m1 new Mat(c:\\learnEmgucv\\lena_fillwhite.jpg, ImreadModes.Grayscale);Mat mask1 new Mat();//二值化CvInvoke.Threshold(m1, mask1, 250, 1, ThresholdType.Binary);CvInvoke.Rectangle(m, rect, new MCvScalar(255, 255, 255), 1);//标记之后再调用GrabCut使用InitWithMask参数CvInvoke.GrabCut(m, mask1, rect, bg, fg, 2, GrabcutInitType.InitWithMask);Matrixbyte matrx new Matrixbyte(mask1.Rows, mask1.Cols);mask1.CopyTo(matrx);for (int i 0; i matrx.Cols; i)for (int j 0; j matrx.Rows; j)if (matrx[i, j] 0 || matrx[i, j] 2)matrx[i, j] 0;elsematrx[i, j] 255;Mat midm2 new Mat();midm2 matrx.Mat;Mat midm1 new Mat();CvInvoke.CvtColor(midm2, midm1, ColorConversion.Gray2Bgr);Mat mout new Mat();CvInvoke.BitwiseAnd(m, midm1, mout);CvInvoke.Imshow(mout, mout);}输出结果如下图所示 图8-7 Grabcut法分离前景 由于.net平台下C#和vb.NET很相似本文也可以为C#爱好者提供参考。
学习更多vb.net知识请参看vb.net 教程 目录