目标

在这一章当中

  • 看到 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_BGDcv2.GC_FGDcv2.GC_PR_BGDcv2.GC_PR_FGD,或简单地通过0,1,2,3
  • rect - 它是包含格式为 (x,y,w,h) 的前景对象的矩形的坐标
  • bdgModel , fgdModel - 这些是算法内部使用的数组。只需创建两个大小为 (1,65) 的 np.float64 类型零数组
  • iterCount - 算法应该运行的迭代次数
  • mode 应该是cv2.GC_INIT_WITH_RECTcv2.GC_INIT_WITH_MASK或组合,这决定了是绘制矩形还是最终的修饰笔触。

首先,看看矩形模式( rectangular mode)。加载图像,然后创建一个类似的蒙版图像。创建fgdModelbgdModel。并给出矩形参数。这一切都是直截了当的。让算法迭代运行 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算法的交互式前景提取相关推荐

  1. OpenCV使用 GrabCut 算法进行交互式前景提取

    OpenCV使用 GrabCut 算法进行交互式前景提取 1. 效果图 2. 源码 参考 这篇博客将介绍如何使用Python,OpenCV中的GrabCut 算法来提取图像中的前景,并为此创建一个交互 ...

  2. OpenCV中的图像处理 —— 霍夫线 / 圈变换 + 图像分割(分水岭算法) + 交互式前景提取(GrabCut算法)

    OpenCV中的图像处理 -- 霍夫线 / 圈变换 + 图像分割(分水岭算法) + 交互式前景提取(GrabCut算法)

  3. OpenCV系列之交互式前景提取使用GrabCut算法 | 三十五

    目标 在本章中, 我们将看到GrabCut算法来提取图像中的前景 我们将为此创建一个交互式应用程序. 理论 GrabCut算法由英国微软研究院的Carsten Rother,Vladimir Kolm ...

  4. 【OpenCV-Python】教程:3-16 利用Grabcut交互式前景提取

    OpenCV Python Grabcut分割 [目标] Grabcut 算法 创建一个交互程序 [理论] 从用户角度是如何工作的呢?用户在需要的目标上初始绘制一个矩形,前景目标必须完全在矩形内部,算 ...

  5. 图像分割与提取:交互式前景提取(附OpenCV代码实现)

    一.简介 经典的前景提取技术主要使用纹理(颜色)信息,如魔术棒工具,或根据边缘(对比度)信息,如智能剪刀等完成.2004 年,微软研究院(剑桥)的 Rother 等人在论文 GrabCut: Inte ...

  6. Python OpenCV 交互式前景提取 自动抠图

    这是需要抠图的原图像,文件名为 "messi5.jpg" 使用矩形方式处理: # -*- coding: utf-8 -*-import numpy as np import cv ...

  7. 迭代图像切割技术的交互式前景提取

    ----- -----<"GrabCut" - Interactive Foreground Extraction using Iterated Graph Cuts> ...

  8. python opencv图像处理算法之GrabCut算法

    GrabCut算法 通常情况下,我们需要图像进行前景后景进行分离,有的时候也许我们仅仅是需要前景.本次教程我们将介绍GrabCut算法进行交互式前景提取. GrabCut是一种基于图切割的图像分割方法 ...

  9. opencv入门:使用交互式进行前景提取

    交互式前景提取 在开始提取前景之前,先用一个矩形框指定前景区域所在的大致位置范围,然后不断的迭代的分割,直到达到最好的效果,经过上述处理,结果可能不理想,存在前景没有提取,或背景被提取,此时需要用户干 ...

最新文章

  1. Sundown EK:漏洞利用工具中的抄袭大师
  2. android 常用渐变背景绘制
  3. Redis集群部署文档(Ubuntu15.10系统)
  4. jquery--- 属性和样式的操作 设置和获取HTML、文本和值、焦点事件
  5. cv2.error: opencv(4.4.0)_【从零学习OpenCV 4】图像金字塔
  6. 模板引擎-1-基础概念和是使用小案例
  7. 36.windbg-!peb(手工分析PEB结构)
  8. 【题解】PTA-Python题库 浙大版《Python 程序设计》题目集题解索引
  9. z世代消费力白皮书_2019 Z世代消费力白皮书,洞悉2.6亿年轻人消费倾向
  10. cad图纸问号怎么转换文字_CAD中文图纸中文字体变成问号怎么办?不慌这几步教你轻松解决...
  11. 怎么样实现一台电脑上两个mysql自由切换版本
  12. 学校计算机怎么连接自己的热点,笔记本电脑怎么连接手机热点(手机热点开启及连接方法)...
  13. Python练习——用循环求100以内7的倍数
  14. 手机端(APP点灯blinker)-PC端(Node-red)-设备端(ESP32)-客户端(MQTTX客户端)四者之间的通信——通过MQTT通信(上)
  15. 建个网站需要多少钱?
  16. 手机端与PC端在线预览PDF
  17. 抖音数据 - 网民评论数据采集,分析
  18. bootstrap地址选择(全国省市选择、定位)功能
  19. python判断是否包含某数字_python如何判断数组里是否有某个数字
  20. Ableton Max for Live Collection ALP 音频MIDI效果合成控制设备拓展合集

热门文章

  1. 向量点乘的图形学意义
  2. PHP房屋租售信息管理系统可以用wamp、phpstudy运行定制开发mysql数据库BS模式
  3. Ozone Security:基于证书的Block Access Token认证
  4. java md密码加密_JavaSE_对密码进行MD5加密
  5. mysql四舍五入函数
  6. QT,QT/E,Qtopia,qt creator的联系与区别
  7. python文件保存在哪里_Python文件路径是什么?怎么写?
  8. 管理软件风险,防患于未然
  9. 【板栗糖GIS】twinmotion—如何在twinmotion中制作会飘动的各国国旗
  10. 完全卸载docker