图像处理学习笔记-使用GrabCut简单抠图

286 阅读1分钟

概述

本篇博客主要记录如何使用opencv的grabCut对图片进行自动抠图,对于前后景区别比较明显的场景,效果还是不错的。

代码示例

例子的地址

例子为CMake项目,目前只在MacOS上运行。运行项目中的Target OpenCVForegroundExtractor,可查看效果

需要的输入

使用grabCut需要指定一个大概的初始值。可以通过一张mask图或者一个矩形范围告诉grabCut哪里可能有前景图,哪里可能是背景图。不管是指定矩形还是mask图,最终都会生成一张mask图,mask图中的像素取值从0到3,定义如下

enum GrabCutClasses {
    GC_BGD    = 0,  // 确定是背景
    GC_FGD    = 1,  // 确定是前景
    GC_PR_BGD = 2,  // 可能是背景
    GC_PR_FGD = 3   // 可能是前景
};

API介绍

cv::grabCut(_processImage, _initialMask, _initialRect, _bgModel, _fgModel, 12, cv::GC_INIT_WITH_RECT);

分别介绍下grabCut的参数:

  • _processImage, 输入的图像
  • _initialMask,mask图像,如果最后一个参数是cv::GC_INIT_WITH_MASK,_initialMask不能为空
  • _initialRect,矩形区域,如果最后一个参数是cv::GC_INIT_WITH_RECT,mask图像可以为空图像
  • _bgModel和_fgModel是grabCut用来做缓存区的两个参数,可以传空cv::Mat
  • 最后一个就是初始化模式和其他flag

使用mask抠图

通过grabCut最终得到一个mask图像,可以通过如下方式处理原图

auto bitMask = maskImage & 1;
cv::Mat outputImage;
originImage.copyTo(outputImage, bitMask);

最终效如下:

image.png