概述
本篇博客主要记录如何使用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);
最终效如下: