OpenCV用GrabCut算法分割图像

OpenCV用GrabCut算法分割图像,物体通常有自己特有的颜色,通过识别颜色接近的区域,通常可以提取出这些颜色。OpenCV提供了一种常用的图像分割算法,即GrabCut算法。GrabCut算法比较复杂,计算量也很大,但结果通常很精确。如果要从静态图像中提取前景物体(例如从图像中剪切一个物体,并粘贴到另一幅图像),最好采用GrabCut算法。

如何实现

cv::grabCut函数的用法非常简单,只需要输入一幅图像,并对一些像素做上“属于背景”或“属于前景”的标记即可。根据这个局部标记,算法将计算出整幅图像的前景/背景分割线。 一种指定输入图像局部前景/背景标签的方法是定义一个包含前景物体的矩形:

        // 定义一个带边框的矩形
        // 矩形外部的像素会被标记为背景
        cv::Rect rectangle(5,70,260,120);

这段代码定义了图像中的一个区域:

OpenCV用GrabCut算法分割图像

矩形之外的像素都会被标记为背景。调用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_FGDcv::GC_FGD的像素,可以检查第一位的值,代码如下所示:

        // 用“按位与”运算检查第一位
        result= result&1; // 如果是前景像素,结果为1

这可能是因为这几个常量被定义的值为1和3,而另外两个(cv::GC_BGDcv::GC_PR_BGD)被定义为0和2。本例因为分割图像不含cv::GC_FGD像素(只输入了cv::GC_BGD像素),所以得到的结果是一样的。

得到的图像如下所示:

OpenCV用GrabCut算法分割图像

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!