using System;
using OpenCvSharp;
namespace Grabcut图像分割
{
class Program
{
static void Main(string[] args)
{
/*
* Grabcut 使用高斯混合模型估计目标区域的背景和前景,实现图像分割
* -函数原型
* void Cv2.GrabCut(InputArray img, InputOutputArray mask, Rect rect, InputOutputArray bgdModel,
* InputOutputArray fgdModel, int iterCount, GrabCutModes mode)
* -img: 输入的待分割图像(CV_8U数据类型的三通道图像)
* -mask: 输入、输出的CV_8U单通道掩码图像
* -rect: 包含对象的roi区域,尽在mode == GC_INIT_WITH_RECT时使用
* -bgdModel: 背景模型的临时数组
* -fgdModel: 前景模型的临时数组
* -iterCount: 算法迭代次数
* -mode: 分割模式标志
*/
string picPath = @"输入图片路径";
Mat img = Cv2.ImRead(picPath);
if (img.Empty())
{
Console.WriteLine("请检测图片路径是否正确");
return;
}
//矩形区域绘制
Mat imgRect = new Mat();
img.CopyTo(imgRect);
Rect rect = new Rect(200, 300, 150, 150);
Cv2.Rectangle(imgRect, rect, new Scalar(255, 255, 255), 2);
Cv2.ImShow("选择矩形区域", imgRect);
//分割图像
Mat bgdModel = Mat.Zeros(1, 65, MatType.CV_64FC1);
Mat fbdModel = Mat.Zeros(1, 65, MatType.CV_64FC1);
Mat mask = Mat.Zeros(img.Size(), MatType.CV_8UC1);
Cv2.GrabCut(img, mask, rect, bgdModel, fbdModel, 5, GrabCutModes.InitWithRect);
//重绘分割出的前景
Mat result = new Mat();
for (int i = 0; i < mask.Rows; i++)
{
for (int j = 0; j < mask.Cols; j++)
{
int n = mask.At<byte>(i, j);
if (n == 1 || n == 3)//保留前景
{
mask.At<byte>(i, j) = 255;
}
else//剔除背景
{
mask.At<byte>(i, j) = 0;
}
}
}
Cv2.BitwiseAnd(img, img, result, mask);
Cv2.ImShow("分割结果", result);
Cv2.WaitKey(0);
}
}
}