OpenCV GrabCut算法前景分割和提取
目录
一、OpenCv Grabcut算法:前景提取与分割(Foreground segmentation and extraction)
(一)算法工作原理
(二)opencv函数cv2.grabCut
(三)实现opencv的带有边框的GrabCut初始化算法
(四)输出结果显示
(五)小结
一、OpenCv Grabcut算法:前景提取与分割(Foreground segmentation and extraction)
利用Mast R-CNN或U-Net生成的掩膜不完美,可以使用GrabCut来清理这些分割掩膜。
(一)算法工作原理
1、接收输入图像,参数一:想分割的图像中对象的位置的边界框;参数二:一种精确分割图像前景和背景的方法
2、 迭代下列操作
- 使用高斯混合模型(gaussian mixture model)估计(estimate)前景和背景颜色分布
- 在像素标签上(pixels labels)构造一个马尔可夫随机场(Markov random field)(如前景与背景)。
- 应用图切割优化(Graph cut optimization)来达到最终的分割
(二)opencv函数cv2.grabCut
grabCut(img, mask, rect, bgdModel, fgdModel, iterCount, mode) -> mask, bgdModel, fgdModel
参数说明
- img:输入图像,GrabCut假设它是一个8位的3通道图像(即, BGR信道顺序中的无符号8位整数)。
- mask:输入/输出掩膜。假设该掩膜是一个单通道图像,数据类型为无符号8位整数。如果你使用边界框初始化(第七个参数mode设为cv2.GC_INIT_WITH_RECT),这个掩膜会自动初始化。否则,GrabCut假设正在执行掩码初始化(第七个参数设为cv2.GC_INIT_WITH_MASK)。
- rect:包含我们要分割的区域的边框矩形。此参数仅在将模式设置为cv2.GC_INIT_WITH_MASK时使用)。
- bgdModel: GrabCut内部建模背景时使用的临时数组。
- fgdModel: GrabCut在建模前景时使用的临时数组。
- iterCount:GrabCut在对前景和背景建模时执行的迭代次数。迭代次数越多,GrabCut运行的时间越长,理想情况下,结果会更好。
- model:要么cv2.GC_INIT_WITH_RECT或cv2.GC_INIT_WITH_MASK,这分别取决于你是用一个边框还是一个掩码初始化GrabCut。
- OpenCV的GrabCut实现返回一个3元组:
- mask:应用GrabCut后的输出掩模
- fgdMode:用于建模背景的临时数组(可以忽略此值)
- fgdModel:用于建模前景的临时数组(同样可以忽略此值)
(三)实现opencv的带有边框的GrabCut初始化算法
边界框的实现方法:将指定在图像中分割的对象的边界框,只要算法生成一个边界框,就可以将它与GrabCut结合使用。边界框的实现方法如下:
- 手动检查图像并标记边框的(x,y)坐标
- 利用Haar级联
- 利用HOG+线性SVM检测目标
- 利用基于深度学习的对象检测器,如Faster R-CNN,SSDs,YOLO等
代码如下:
- 初始化GrabCut的边界框初始化方法
构造参数解析器并解析参数,该脚本处理两个命令行参数
–image:输入图像。在"D:\image目录中使用guangtou.png图像。
–iter:GrabCut迭代要执行的次数,较小的值会导致更快的总体时间,较大的值会导致较慢的运行时间(但理想情况下更好的分割结果)
# import the necessary packages
import numpy as np
import argparse
import time
import cv2
import os
# 构造参数解析器并解析参数
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", type=str,default=os.path.sep.join([r"D:\image", "guangtou.png"]),help="path to input image that we'll apply GrabCut to")
ap.add_argument("-c", "--iter", type=int, default=10,help="# of GrabCut iterations (larger value => slower runtime)")
args = vars(ap.parse_args())
- 加载输入图像,并为相等大小的掩膜分配空间
# load the input image from disk and then allocate memory for the
# output mask generated by GrabCut -- this mask should hae the same
# spatial dimensions as the input image
image = cv2.imread(args["image"])
mask = np.zeros(image.shape[:2], dtype="uint8")
创建的掩膜很快就被GrabCut算法的结果填充。
- 手动定义guangtou.png中的人脸坐标,用矩形选择该区域,前两个参数为矩形左上角顶点,后两个参数为长和宽。
关于像素点的确定,可以使用Photoshop或GIMP等免费图形编辑软件。这里人脸rect坐标是手动确定的,任何对象检测器都可以完成这项工作,可以选择Haar、HOG或基于dll的面检测器来查找边界。
# define the bounding box coordinates that approximately define my
# face and neck region (i.e., all visible skin)
rect = (80, 20, 140, 230)
- 执行GrabCut算法,并对输入进行边界框初始化
# allocate memory for two arrays that the GrabCut algorithm internally
# uses when segmenting the foreground from the background
fgModel = np.zeros((1, 65), dtype="float") #两个空数组,便于在从背景分割前景时使用(fgModel和bgModel)
bgModel = np.zeros((1, 65), dtype="float")
# apply GrabCut using the the bounding box segmentation method
start = time.time()
#GrabCut返回我们填充的掩码以及两个我们可以忽略的数组
(mask, bgModel, fgModel) = cv2.grabCut(image, mask, rect, bgModel,fgModel, iterCount=args["iter"], mode=cv2.GC_INIT_WITH_RECT)
end = time.time()
print("[INFO] applying GrabCut took {:.2f} seconds".format(end - start))
- 继续对掩膜进行后期处理
# the output mask has for possible output values, marking each pixel
# in the mask as (1) definite background, (2) definite foreground,
# (3) probable background, and (4) probable foreground
values = (("Definite Background", cv2.GC_BGD),("Probable Background", cv2.GC_PR_BGD),("Definite Foreground", cv2.GC_FGD),("Probable Foreground", cv2.GC_PR_FGD),
)
# loop over the possible GrabCut mask values
for (name, value) in values:# construct a mask that for the current valueprint("[INFO] showing mask for '{}'".format(name))valueMask = (mask == value).astype("uint8") * 255# display the mask so we can visualize itcv2.imshow(name, valueMask)cv2.waitKey(0)
定义了输出的GrabCut掩膜中可能的值,包括我们确定的/可能的背景和前景。然后继续对这些值进行循环,以便我们可以可视化每个值。在循环中,我们为当前值构造一个掩码,并显示它,直到按下任何键为止。
- 在确定的/可能的背景和前景已经显示后,我们的代码将开始生成一个outputMask和一个输出图像(背景被掩盖)
# 找到所有确定的背景或可能的背景像素,并将它们设置为0 ,所有其他像素应该标记为1(前景)
outputMask = np.where((mask == cv2.GC_BGD) | (mask == cv2.GC_PR_BGD), 0, 1)
# scale the mask from the range [0, 1] to [0, 255]
outputMask = (outputMask * 255).astype("uint8")
# apply a bitwise AND to the image using our mask generated by
# GrabCut to generate our final output image
output = cv2.bitwise_and(image, image, mask=outputMask)
此时,我们有:
为grabCut函数准备的输入,包括输入图像、掩模、矩形坐标以及fgModel和bgModel零数组。注意,rect坐标是手动确定的。
执行GrabCut算法。
生成并可视化我们确定的/可能的背景和前景腌膜。
生成GrabCut输出掩膜(outputMask)和带有背景掩膜的输出图像(output)
- 继续并显示我们的最终结果
# show the input image followed by the mask and output generated by
# GrabCut and bitwise masking
cv2.imshow("Input", image) #原图
cv2.imshow("GrabCut Mask", outputMask) #GrabCUt生成的掩膜mask
cv2.imshow("GrabCut Output", output) #只有前景的原始图像
cv2.waitKey(0)
(四)输出结果显示
(五)小结
基于深度学习的分割网络,如Faster R-CNN和U-Net,可以自动生成从背景中分割物体(前景)的掩膜——这并不意味着GrabCut在深度学习时代是没意义的。虽然Faster R-CNN和U-Net是超级强大的方法,但它们会导致生成的掩膜混乱粗糙。我们可以用GrabCut来帮助清理这些掩膜得到更好的结果。
OpenCV GrabCut算法前景分割和提取相关推荐
- OpenCV GrabCut算法:前景分割和提取
目录 一.OpenCv Grabcut算法:前景提取与分割(Foreground segmentation and extraction) (一)算法工作原理 (二)opencv函数cv2.grabC ...
- Python OpenCV GrabCut进行前景分割和提取
Python OpenCV GrabCut进行前景分割和提取 1. 效果图 1.1 边界框GrabCut效果图 1.2 Mask GrabCut效果图 2. GrabCut原理 2.1 GrabCut ...
- python 黑白tif提取边界像素坐标_OpenCV GrabCut算法:前景分割和提取
点击上方"蓝色小字"关注我呀 文章翻译自光头哥哥的博客,原文链接: https://www.pyimagesearch.com/2020/07/27/opencv-grabcut- ...
- OpenCV——Grabcut算法
Grabcut 算法主要运用于计算机视觉中的前背景分割,立体视觉和抠图等.该算法利用了图像中的纹理(颜色)信息和边界(反差)信息,只要少量的用户交互操作即可得到比较好的分割结果. 1. Grabcut ...
- opencv曝光算法_OpenCV特征点提取算法对比
除了我们熟知的SIFT.SURF.ORB等特征点提取算法,OpenCV中还提供了十余种特征点提取算法.最近在整理以往的ppt和报告,看到其中一页ppt,发现已经忘得差不多了,就再写篇博客复习下好了,这 ...
- OpenCV - GrabCut 算法抠图(Python实现)
原理 开始时用户需要用一个矩形将前景区域框住(前景区域应该完全被包括在矩形框内部).然后算法进行迭代式分割直达达到最好结果. 函数 mask, bgdModel, fgdModel = cv2.gra ...
- java grabcut,在OpenCV中应用GrabCut算法后获取相同的图像
我使用GrabCut算法来分割我的图像my image,以检测我图像中的柑橘(水果)作为前景并从背景中减去它 . 为此,首先我必须在我的对象(水果)周围选择2个点,用于在我的对象(水果)周围绘制矩形, ...
- OpenCV使用 GrabCut 算法进行交互式前景提取
OpenCV使用 GrabCut 算法进行交互式前景提取 1. 效果图 2. 源码 参考 这篇博客将介绍如何使用Python,OpenCV中的GrabCut 算法来提取图像中的前景,并为此创建一个交互 ...
- OpenCV系列之交互式前景提取使用GrabCut算法 | 三十五
目标 在本章中, 我们将看到GrabCut算法来提取图像中的前景 我们将为此创建一个交互式应用程序. 理论 GrabCut算法由英国微软研究院的Carsten Rother,Vladimir Kolm ...
最新文章
- activexobject对象不能创建_【设计模式】建造者模式:你创建对象的方式有它丝滑吗?...
- python3多进程写时拷贝_Python实现多进程的详解(附示例)
- Boost.Function 库示例
- python语言属于哪一种语言_Python与Java:你应该学习哪种语言,他们有什么区别?...
- native react 更新机制_react-native热更新全方位讲解
- MySQL数据库应用形考_2020国开中优教育《MySQL数据库应用》形考任务题库
- BZOJ 3053 The Closest M Points
- 火狐扩展教程_5个Firefox扩展保护您的隐私
- 1020-锰硅、硅铁、郑醇、焦煤、焦炭、尿素、纯碱、郑煤、EG、PVC跌停,郑煤期权,看涨期权跌停,看跌期权涨停,做市商停止报价
- 基于STM32超声波测距
- 如何排版 微信公众号「代码块」之 MarkEditor
- 怎么把图片的分辨率调高?如何调整图片分辨率?
- uniapp使用canvas完成手写电子签名
- python3代码编程规范(命名、空格、注释、代码布局、编程建议等)
- WiFi辐射比手机电脑辐射数值小 60厘米外基本为0
- 基于Android开发的在线考试系统(附带源码)
- 【转】Linux开启FTP服务和修改FTP密码
- 迪赛智慧数——柱状图(极坐标扇图):2021年全国出生人口数量TOP10省份
- “评论实名制”,10月1日即将实施
- 【财务】FMS财务管理系统---存货管理