opencv29:使用Grabcut算法的交互式前景提取
目标
在这一章当中
- 看到
GrabCut
算法来提取图像中的前景 - 为此创建一个交互式应用程序
理论
GrabCut 算法由英国剑桥微软研究院的 Carsten Rother、Vladimir Kolmogorov 和 Andrew Blake 设计。在他们的论文“GrabCut”中:使用迭代图切割的交互式前景提取。需要一种算法以最少的用户交互进行前景提取,结果是 GrabCut。
从用户的角度来看它是如何工作的?最初用户在前景区域周围绘制一个矩形(前景区域应该完全在矩形内)。然后算法对其进行迭代分割以获得最佳结果。完毕。但是在某些情况下,分割不会很好。例如,它可能将某些前景区域标记为背景,反之亦然。在这种情况下,用户需要进行精细的修饰。只需在存在一些错误结果的图像上进行一些描边即可。Strokes 基本上是说 “嘿,这个区域应该是前景,你把它标记为背景,在下一次迭代中纠正它” 或者它的相反背景。然后在下一次迭代中,将获得更好的结果。
见下图。第一位球员和足球被封闭在一个蓝色矩形中。然后用 白色笔触(表示前景)和黑色笔触(表示背景) 进行一些最终修饰,最终得到了一个不错的结果。
这背后会发生什么?
- 用户输入矩形。此矩形之外的所有内容都将被视为确定的背景(这就是之前提到的矩形应包含所有对象的原因)。矩形内的一切都是未知的。类似地,任何指定前景和背景的用户输入都被视为硬标签,这意味着它们不会在过程中发生变化。
- 计算机根据所提供的数据进行初始标记。标记前景和背景像素(或硬标记)
- 现在使用高斯混合模型(GMM)对前景和背景进行建模。
- 根据提供的数据,GMM 学习并创建新的像素分布。即,未知像素被标记为可能的前景或可能的背景,这取决于它与其他硬标记像素在颜色统计方面的关系(就像聚类一样)。
- 图形是根据此像素分布构建的。图中的节点是像素。添加了另外两个节点**,Source node和Sink node**。每个前景像素都连接到 Source 节点,每个背景像素都连接到 Sink 节点。
- 将像素连接到源节点/结束节点的边的权重由像素为前景/背景的概率定义。像素之间的权重由边缘信息或像素相似度定义。如果像素颜色存在较大差异,则它们之间的边缘将获得较低的权重。
- 然后使用
mincut
算法对图进行分割。它以最小的代价函数将图切割成两个分离的源节点和汇节点。成本函数是被切割的边的所有权重的总和。剪切后,所有连接到源节点的像素成为前景,连接到接收节点的像素成为背景。 - 该过程一直持续到分类收敛。
示意图如下所示(图片提供:[http : //www.cs.ru.ac.za/research/g02m1682/](http : //www.cs.ru.ac.za/research/g02m1682/))
演示
现在使用 OpenCV 实现grabcut算法。OpenCV 有函数cv2.grabCut()
。我们将首先看到它的参数:
mask, bgdModel, fgdModel = cv2.grabCut(img, mask, rect, bgdModel, fgdModel, iterCount[, mode] )
- img - 输入图像
- mask - 遮罩图像,指定哪些区域是背景、前景或可能的背景/前景等。由以下标志完成,
cv2.GC_BGD
,cv2.GC_FGD
,cv2.GC_PR_BGD
,cv2.GC_PR_FGD
,或简单地通过0,1,2,3- rect - 它是包含格式为 (x,y,w,h) 的前景对象的矩形的坐标
- bdgModel , fgdModel - 这些是算法内部使用的数组。只需创建两个大小为 (1,65) 的 np.float64 类型零数组
- iterCount - 算法应该运行的迭代次数
- mode 应该是
cv2.GC_INIT_WITH_RECT
或cv2.GC_INIT_WITH_MASK
或组合,这决定了是绘制矩形还是最终的修饰笔触。
首先,看看矩形模式( rectangular mode)。加载图像,然后创建一个类似的蒙版图像。创建fgdModel
和bgdModel
。并给出矩形参数。这一切都是直截了当的。让算法迭代运行 5 次。模式应该是cv2.GC_INIT_WITH_RECT
,这是因为使用的是矩形。然后运行grabcut
。它修改蒙版图像。在新的蒙版图像中,像素将被标记为四个标志,表示上面指定的背景/前景。所以修改掩码,使得所有 0 像素和 2 像素都置为 0(即背景),所有 1 像素和 3 像素均置为 1(即前景像素)。现在最终的mask准备好了。只需将其与输入图像相乘即可得到分割图像。
import cv2
import numpy as np
from matplotlib import pyplot as pltimg = cv2.imread('messi2.jpg')
mask = np.zeros(img.shape[:2], np.uint8)
cv2.imwrite('dd.jpg', mask)bgdModel = np.zeros((1, 65), np.float64)
fgdModel = np.zeros((1, 65), np.float64)rect = (50, 50, 450, 290)
cv2.grabCut(img, mask, rect, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_RECT)mask2 = np.where((mask==2)|(mask==0), 0, 1).astype('uint8')
img = img * mask2[:,:, np.newaxis]plt.imshow(img)
plt.colorbar()
plt.show()
查看以下结果:
哎呀,梅西的头发不见了。谁喜欢没有头发的梅西?我们需要把它弄回来。因此,将使用 1 像素(当然是前景) 进行精细修饰。同时,一些地面出现了我们不想要的图片,还有一些标志, 也需要移除它们。在那里,提供了一些 0 像素的修饰(当然是背景)。因此,正如现在所说的那样,修改了之前案例中的结果掩码。
实际做的是,在绘画应用程序中打开输入图像并为图像添加了另一个图层。在油漆中使用画笔工具,在这个新图层上用白色标记错过的前景(头发、鞋子、球等)和用黑色标记不需要的背景(如标志、地面等)。然后用灰色填充剩余的背景。 然后在 OpenCV 中加载该蒙版图像,编辑我们获得的原始蒙版图像,并在新添加的蒙版图像中使用相应的值。检查下面的代码:
# newmask is the mask image by manually labelled
newmask = cv2.imread('messi-new-mask.jpg', 0)
# wherever it is marked white (sure foreground), change mask=1
# wherever it is marked black (sure background), change mask=0
mask[newmask == 0] = 0
mask[newmask == 255] = 1
mask, bgdModel, fgdModel = cv2.grabCut(img,mask,None,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_MASK)
mask = np.where((mask==2)|(mask==0),0,1).astype('uint8')
img = img*mask[:,:,np.newaxis]
plt.subplot(121)
plt.imshow(mask)plt.subplot(122)
plt.imshow(img)
plt.colorbar()
plt.show()
在这里,可以直接进入掩码模式,而不是在 rect 模式下初始化。只需用 2 像素或 3 像素(可能的背景/前景)标记蒙版图像中的矩形区域。然后像我们在第二个示例中所做的那样用 1 像素标记我们的sure_foreground
。然后直接应用带有mask模式的grabCut
函数。
附加资源
- https://docs.opencv.org/4.1.2/d8/d83/tutorial_py_grabcut.html
- https://dl.acm.org/citation.cfm?id=1015720
- https://docs.opencv.org/4.1.2/d7/d1b/group__imgproc__misc.html#ga909c1dda50efcbeaa3ce126be862b37f
opencv29:使用Grabcut算法的交互式前景提取相关推荐
- OpenCV使用 GrabCut 算法进行交互式前景提取
OpenCV使用 GrabCut 算法进行交互式前景提取 1. 效果图 2. 源码 参考 这篇博客将介绍如何使用Python,OpenCV中的GrabCut 算法来提取图像中的前景,并为此创建一个交互 ...
- OpenCV中的图像处理 —— 霍夫线 / 圈变换 + 图像分割(分水岭算法) + 交互式前景提取(GrabCut算法)
OpenCV中的图像处理 -- 霍夫线 / 圈变换 + 图像分割(分水岭算法) + 交互式前景提取(GrabCut算法)
- OpenCV系列之交互式前景提取使用GrabCut算法 | 三十五
目标 在本章中, 我们将看到GrabCut算法来提取图像中的前景 我们将为此创建一个交互式应用程序. 理论 GrabCut算法由英国微软研究院的Carsten Rother,Vladimir Kolm ...
- 【OpenCV-Python】教程:3-16 利用Grabcut交互式前景提取
OpenCV Python Grabcut分割 [目标] Grabcut 算法 创建一个交互程序 [理论] 从用户角度是如何工作的呢?用户在需要的目标上初始绘制一个矩形,前景目标必须完全在矩形内部,算 ...
- 图像分割与提取:交互式前景提取(附OpenCV代码实现)
一.简介 经典的前景提取技术主要使用纹理(颜色)信息,如魔术棒工具,或根据边缘(对比度)信息,如智能剪刀等完成.2004 年,微软研究院(剑桥)的 Rother 等人在论文 GrabCut: Inte ...
- Python OpenCV 交互式前景提取 自动抠图
这是需要抠图的原图像,文件名为 "messi5.jpg" 使用矩形方式处理: # -*- coding: utf-8 -*-import numpy as np import cv ...
- 迭代图像切割技术的交互式前景提取
----- -----<"GrabCut" - Interactive Foreground Extraction using Iterated Graph Cuts> ...
- python opencv图像处理算法之GrabCut算法
GrabCut算法 通常情况下,我们需要图像进行前景后景进行分离,有的时候也许我们仅仅是需要前景.本次教程我们将介绍GrabCut算法进行交互式前景提取. GrabCut是一种基于图切割的图像分割方法 ...
- opencv入门:使用交互式进行前景提取
交互式前景提取 在开始提取前景之前,先用一个矩形框指定前景区域所在的大致位置范围,然后不断的迭代的分割,直到达到最好的效果,经过上述处理,结果可能不理想,存在前景没有提取,或背景被提取,此时需要用户干 ...
最新文章
- Sundown EK:漏洞利用工具中的抄袭大师
- android 常用渐变背景绘制
- Redis集群部署文档(Ubuntu15.10系统)
- jquery--- 属性和样式的操作 设置和获取HTML、文本和值、焦点事件
- cv2.error: opencv(4.4.0)_【从零学习OpenCV 4】图像金字塔
- 模板引擎-1-基础概念和是使用小案例
- 36.windbg-!peb(手工分析PEB结构)
- 【题解】PTA-Python题库 浙大版《Python 程序设计》题目集题解索引
- z世代消费力白皮书_2019 Z世代消费力白皮书,洞悉2.6亿年轻人消费倾向
- cad图纸问号怎么转换文字_CAD中文图纸中文字体变成问号怎么办?不慌这几步教你轻松解决...
- 怎么样实现一台电脑上两个mysql自由切换版本
- 学校计算机怎么连接自己的热点,笔记本电脑怎么连接手机热点(手机热点开启及连接方法)...
- Python练习——用循环求100以内7的倍数
- 手机端(APP点灯blinker)-PC端(Node-red)-设备端(ESP32)-客户端(MQTTX客户端)四者之间的通信——通过MQTT通信(上)
- 建个网站需要多少钱?
- 手机端与PC端在线预览PDF
- 抖音数据 - 网民评论数据采集,分析
- bootstrap地址选择(全国省市选择、定位)功能
- python判断是否包含某数字_python如何判断数组里是否有某个数字
- Ableton Max for Live Collection ALP 音频MIDI效果合成控制设备拓展合集