OpenCV用GrabCut算法分割图像,物体通常有自己特有的颜色,通过识别颜色接近的区域,通常可以提取出这些颜色。OpenCV提供了一种常用的图像分割算法,即GrabCut算法。GrabCut算法比较复杂,计算量也很大,但结果通常很精确。如果要从静态图像中提取前景物体(例如从图像中剪切一个物体,并粘贴到另一幅图像),最好采用GrabCut算法。
如何实现
cv::grabCut
函数的用法非常简单,只需要输入一幅图像,并对一些像素做上“属于背景”或“属于前景”的标记即可。根据这个局部标记,算法将计算出整幅图像的前景/背景分割线。 一种指定输入图像局部前景/背景标签的方法是定义一个包含前景物体的矩形:
// 定义一个带边框的矩形
// 矩形外部的像素会被标记为背景
cv::Rect rectangle(5,70,260,120);
这段代码定义了图像中的一个区域:
矩形之外的像素都会被标记为背景。调用cv::grabCut
时,除了需要输入图像和分割后的图像,还需要定义两个矩阵,用于存放算法构建的模型,代码如下所示:
cv::Mat result; // 分割结果(四种可能的值)
cv::Mat bgModel, fgModel; // 模型(内部使用)
// GrabCut分割算法
cv::grabCut(image, // 输入图像
result, // 分割结果
rectangle, // 包含前景的矩形
bgModel, fgModel, // 模型
5, // 迭代次数
cv::GC_INIT_WITH_RECT); // 使用矩形
注意,我们在函数的中用cv::GC_INIT_WITH_RECT
标志作为最后一个参数,表示将使用带边框的矩形模型。输入/输出的分割图像可以是以下四个值之一。
cv::GC_BGD
:这个值表示明确属于背景的像素(例如本例中矩形之外的像素)。cv::GC_FGD
:这个值表示明确属于前景的像素(本例中没有这种像素)。cv::GC_PR_BGD
:这个值表示可能属于背景的像素。cv::GC_PR_FGD
:这个值表示可能属于前景的像素(即本例中矩形之内像素的初始值)。
通过提取值为cv::GC_PR_FGD
的像素,可得到包含分割信息的二值图像,实现代码为:
// 取得标记为“可能属于前景”的像素
cv::compare(result, cv::GC_PR_FGD, result, cv::CMP_EQ);
// 生成输出图像
cv::Mat foreground(image.size(), CV_8UC3, cv::Scalar(255,255,255));
image.copyTo(foreground, result); // 不复制背景像素
要提取全部前景像素,即值为cv::GC_PR_FGD
或cv::GC_FGD
的像素,可以检查第一位的值,代码如下所示:
// 用“按位与”运算检查第一位
result= result&1; // 如果是前景像素,结果为1
这可能是因为这几个常量被定义的值为1和3,而另外两个(cv::GC_BGD
和cv::GC_PR_BGD
)被定义为0和2。本例因为分割图像不含cv::GC_FGD
像素(只输入了cv::GC_BGD
像素),所以得到的结果是一样的。
得到的图像如下所示:
酷客网相关文章:
评论前必须登录!
注册