opencv - py_imgproc - py_grabcut GrabCut 算法提取前景
文章目录
- 使用 GrabCut 算法进行交互式前景提取
- 目标
- 理论
- 演示
使用 GrabCut 算法进行交互式前景提取
目标
在本章中
- 我们将了解 GrabCut 算法如何提取图像中的前景
- 我们将为此创建一个交互式应用程序。
理论
GrabCut 算法由英国剑桥微软研究院的 Carsten Rother、Vladimir Kolmogorov 和 Andrew Blake 设计。在他们的论文 “GrabCut”:使用迭代图切割进行交互式前景提取 中。需要一种以最少的用户交互进行前景提取的算法,结果就是 GrabCut。
从用户的角度来看它是如何工作的?首先,用户在前景区域周围绘制一个矩形(前景区域应完全在矩形内)。然后算法迭代地对其进行分割以获得最佳结果。完成。但在某些情况下,分割效果并不好,例如,它可能将某些前景区域标记为背景,反之亦然。在这种情况下,用户需要进行精细的修饰。只需在存在错误结果的图像上进行一些描边即可。描边基本上表示“嘿,这个区域应该是前景,你将其标记为背景,在下一次迭代中对其进行更正”*或将其相反标记为背景。然后在下一次迭代中,您会得到更好的结果。
参见下图。第一个球员和足球被包裹在一个蓝色矩形中。然后用白色描边(表示前景)和黑色描边(表示背景)进行一些最后的修饰。我们得到了一个不错的结果。

那么背景会发生什么?
- 用户输入矩形。此矩形之外的所有内容都将被视为确定的背景(这就是之前提到您的矩形应包含所有对象的原因)。矩形内的所有内容都是未知的。同样,任何指定前景和背景的用户输入都被视为硬标记,这意味着它们不会在此过程中发生变化。
- 计算机根据我们提供的数据进行初始标记。它标记前景和背景像素(或硬标记)
- 现在使用高斯混合模型 (GMM) 来建模前景和背景。
- 根据我们提供的数据,GMM 学习并创建新的像素分布。也就是说,未知像素根据其与其他硬标记像素在颜色统计方面的关系被标记为可能的前景或可能的背景(这就像聚类)。
- 根据此像素分布构建图形。图中的节点是像素。添加了另外两个节点,源节点和接收器节点。每个前景像素都连接到源节点,每个背景像素都连接到接收器节点。
- 将像素连接到源节点/端节点的边的权重由像素为前景/背景的概率定义。像素之间的权重由边缘信息或像素相似性定义。如果像素颜色差异很大,则它们之间的边缘将获得较低的权重。
- 然后使用最小切割算法对图形进行分割。它将图形切成两个分离的源节点和接收器节点,具有最小成本函数。成本函数是所有被切割边的权重之和。切割后,所有连接到源节点的像素都变为前景,而连接到接收器节点的像素都变为背景。
- 该过程持续进行,直到分类收敛。
如下图所示(图片来源:http://www.cs.ru.ac.za/research/g02m1682/)

演示
现在我们使用 OpenCV 进行 grabcut 算法。OpenCV 有函数 cv.grabCut() 用于此目的。我们
首先将看到它的参数:
- img - 输入图像
- mask - 这是一个掩码图像,我们指定哪些区域是背景、前景或可能的背景/前景等。它通过以下标志完成,cv.GC_BGD、cv.GC_FGD、cv.GC_PR_BGD、cv.GC_PR_FGD,或者简单地将 0、1、2、3 传递给图像。
- rect - 它是包含前景对象的矩形的坐标,格式为 (x,y,w,h)
- bdgModel、fgdModel - 这些是算法内部使用的数组。您只需创建两个大小为 (1,65) 的 np.float64 类型零数组。
- iterCount - 算法应运行的迭代次数。
- mode - 它应该是 cv.GC_INIT_WITH_RECT 或 cv.GC_INIT_WITH_MASK 或两者结合
决定我们绘制的是矩形还是最终的修饰笔触。
首先让我们看看矩形模式。我们加载图像,创建一个类似的遮罩图像。我们创建 fgdModel 和 bgdModel。我们给出矩形参数。这一切都很简单。让算法运行 5 次迭代。模式应该是cv.GC_INIT_WITH_RECT,因为我们使用的是矩形。然后运行 grabcut。它会修改遮罩图像。在新的遮罩图像中,像素将用四个标志标记,表示如上所述的背景/前景。因此,我们修改了掩码,将所有 0 像素和 2 像素都设置为 0(即背景),将所有 1 像素和 3 像素都设置为 1(即前景像素)。现在我们的最终掩码已准备就绪。只需将其与输入图像相乘即可获得分割后的图像。
import numpy as np
import cv2 as cv
from matplotlib import pyplot as pltimg = cv.imread('messi5.jpg')
mask = np.zeros(img.shape[:2],np.uint8)bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)rect = (50,50,450,290)
cv.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv.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 I manually labelled
newmask = cv.imread('newmask.png',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] = 1mask, bgdModel, fgdModel = cv.grabCut(img,mask,None,bgdModel,fgdModel,5,cv.GC_INIT_WITH_MASK)mask = np.where((mask==2)|(mask==0),0,1).astype('uint8')
img = img*mask[:,:,np.newaxis]
plt.imshow(img),plt.colorbar(),plt.show()
请参阅以下结果:

就是这样。在这里,您可以直接进入掩码模式,而不是在矩形模式下初始化。只需用 2 像素或 3 像素(可能的背景/前景)标记掩码图像中的矩形区域。然后用 1 像素标记我们的 sure_foreground,就像我们在第二个示例中所做的那样。然后直接在掩码模式下应用 grabCut函数。
相关文章:
opencv - py_imgproc - py_grabcut GrabCut 算法提取前景
文章目录 使用 GrabCut 算法进行交互式前景提取目标理论演示 使用 GrabCut 算法进行交互式前景提取 目标 在本章中 我们将了解 GrabCut 算法如何提取图像中的前景我们将为此创建一个交互式应用程序。 理论 GrabCut 算法由英国剑桥微软研究院的 Carsten Rother、Vladimir K…...
ChatGPT多模态命名实体识别
ChatGPT多模态命名实体识别 ChatGPT辅助细化知识增强!一、研究背景二、模型结构和代码任务流程第一阶段:辅助精炼知识启发式生成第二阶段:基于…...
04-Dubbo的通信协议
04-Dubbo的通信协议 Dubbo 支持的通信协议 Dubbo 框架提供了自定义的高性能 RPC 通信协议: 基于 TCP 的 Dubbo2 协议 基于 HTTP/2 的 Triple 协议 Dubbo 框架是不和任何通信协议绑定的,对通信协议的支持非常灵活,支持任意的第三方协议&#x…...
开源数据库 - mysql - innodb源码阅读 - 线程启动
线程启动源码 /** Start up the InnoDB service threads which are independent of DDL recovery.*/void srv_start_threads() {if (!srv_read_only_mode) {/* Before 8.0, it was master thread that was doing periodicalcheckpoints (every 7s). Since 8.0, it is the log …...
在美团外卖上抢券 Python来实现
在美团外卖上抢券的 Python 实现 在如今的互联网时代,自动化脚本已经成为了许多用户生活中不可或缺的工具。尤其是在购物、抢券等场景中,自动化脚本能够帮助我们节省大量的时间和精力。今天,我们将一起探索如何使用 Python 编写一个简单的脚…...
【ONLYOFFICE 文档 8.2 版本深度测评】功能革新与用户体验的双重飞跃
引言 在数字化办公的浪潮中,ONLYOFFICE 文档以其强大的在线协作功能和全面的办公套件解决方案,赢得了全球用户的青睐。随着 8.2 版本的发布,ONLYOFFICE 再次证明了其在办公软件领域的创新能力和技术实力。 一.协作编辑 PDF:团队合…...
npm入门教程18:npm发布npm包
一、准备工作 注册npm账号: 前往npm官网注册一个账号。注册过程中需要填写个人信息,并完成邮箱验证。 安装Node.js和npm: 确保你的计算机上已安装Node.js和npm。Node.js的安装包中通常包含了npm。你可以通过运行node -v和npm -v命令来检查它…...
VueSSR详解 VueServerRenderer Nutx
SSR Vue中的SSR(Server-Side Rendering,服务器端渲染)是一种将页面的渲染工作从客户端转移到服务器端的技术。以下是对Vue中SSR的详细解释: 一、SSR的工作原理 在传统的客户端渲染(CSR)中,页面的…...
构建您自己的 RAG 应用程序:使用 Ollama、Python 和 ChromaDB 在本地设置 LLM 的分步指南
在数据隐私至关重要的时代,建立自己的本地语言模型 (LLM) 为公司和个人都提供了至关重要的解决方案。本教程旨在指导您完成使用 Ollama、Python 3 和 ChromaDB 创建自定义聊天机器人的过程,所有这些机器人都托管在您的系统本地。以…...
谷歌浏览器安装axure插件
1.在生成静态原型页面的路径下,找到resources\chrome\axure-chrome-extension.crx,这就是需要的插件了。 2.将axure-chrome-extension.crx重命名成axure-chrome-extension.zip然后解压到指定的文件夹(这个文件夹不能删除, 例如解压到了扩展程…...
Java唯一键实现方案
数据唯一性 1、生成UUID1.1 代码中实现1.2 数据库中实现优点缺点 2、数据库递增主键优点 3、数据库递增序列3.1 创建序列3.2 使用序列优点缺点 在Java项目开发中,对数据的唯一性要求,业务数据入库的时候保持单表只有一条记录,因此对记录中要求…...
opencv - py_imgproc - py_canny Canny边缘检测
文章目录 Canny 边缘检测目标理论OpenCV 中的 Canny 边缘检测其他资源 Canny 边缘检测 目标 在本章中,我们将学习 Canny 边缘检测的概念用于该目的的 OpenCV 函数:cv.Canny() 理论 Canny 边缘检测是一种流行的边缘检测算法。它由 John F. Canny 于1…...
Spring Boot 创建项目详细介绍
上篇文章简单介绍了 Spring Boot(Spring Boot 详细简介!),还没看到的读者,建议看看。 下面,介绍一下如何创建一个 Spring Boot 项目,以及自动生成的目录文件作用。 Maven 构建项目 访问 http…...
70B的模型需要多少张A10的卡可以部署成功,如果使用vLLM
部署一个 70B 的模型(如 defog/sqlcoder-70b-alpha)通常需要考虑多个因素,包括模型的内存需求和你的 GPU 配置。 1. 模型内存需求 大约计算,一个 70B 参数的模型在使用 FP16 精度时大约需要 280 GB 的 GPU 内存。对于 A10 GPU&a…...
clickhouse配置用户角色与权限
首先找到user.xml文件,默认在/etc/clickhouse-server路径下 一、配置角色 找到标签定义 <aaaa><readonly>1</readonly><allow_dll>0</allow_dll> </aaaa>其中aaaa为角色名称,readonly为只读权限(0–代表…...
面试题整理 4
总结整理了某公司面试中值得记录的笔试和问到的问题和答案。 目录 PHP传值和传引用区别?什么情况下用传值?什么情况下用传引用? 传值 传引用 区别 选择传值还是传引用时 简述PHP的垃圾回收机制 二维数组排序 什么是CSRF攻击ÿ…...
React基础大全
文章目录 一、React基本介绍1.虚拟DOM优化1.1 原生JS渲染页面1.2 React渲染页面 2.需要提前掌握的JS知识 二、入门1.React基本使用2.创建DOM的两种方式2.1 使用js创建(一般不用)2.2 使用jsx创建 3.React JSX3.1 JSX常见语法规则3.2 for循环渲染数据 4.模…...
51c大模型~合集10
我自己的原文哦~ https://blog.51cto.com/whaosoft/11547799 #Llama 3.1 美国太平洋时间 7 月 23 日,Meta 公司发布了其最新的 AI 模型 Llama 3.1,这是一个里程碑时刻。Llama 3.1 的发布让我们看到了开源 LLM 有与闭源 LLM 一较高下的能力。 Meta 表…...
【已解决】element-plus配置主题色后,sass兼容问题。set-color-mix-level() is...in Dart Sass 3
项目:vue3vite "scripts": {"dev": "vite","build": "vite build","preview": "vite preview"},"dependencies": {"element-plus/icons-vue": "^2.3.1",&quo…...
JavaWeb——Web入门(4/9)-HTTP协议:请求协议(请求行、请求头、请求体、演示 )
目录 请求协议概述 请求行 请求头 请求体 演示 GET POST 请求协议概述 介绍完了 HTTP 协议的概念以及特点之后,接下来介绍 HTTP 当中的请求协议。 请求协议指的就是请求数据的格式。 HTTP 请求协议在整个 Web 通信中起着至关重要的作用。当用户在浏览器…...
避坑指南:.NET MAUI页面跳转最常见的5个坑点及解决方案(2023最新版)
.NET MAUI页面导航避坑实战:5个高频问题与工业级解决方案 刚接触.NET MAUI的开发者常会在页面跳转环节踩坑——传参莫名丢失、导航堆栈突然崩溃、模态窗口关闭失效...这些问题往往消耗大量调试时间。本文将结合GitHub高星issue和StackOverflow热帖,拆解5…...
Linux核心转储文件生成与调试全指南
1. Linux核心转储文件调试方法详解1.1 核心转储文件概述在Linux系统下,当程序发生崩溃时,系统会生成一个包含程序崩溃时内存映像的文件,称为core文件。这个文件记录了程序崩溃时的内存状态和调试信息,是定位程序崩溃原因的重要工具…...
部署开源的Minecraft服务器智能运维管理系统 Minecraft-Rcon-Manage 自存简易教程
项目地址:Minecraft-Rcon-Manage 前言 笔者最近寻找一款能实现Minecraft服务器RCON远程访问的工具,找到了这个目前正在持续更新、功能丰富的开源项目Minecraft-Rcon-Manage,但实际部署过程中发现作者提供的教程博客无法正常访问,…...
用51单片机+无源蜂鸣器播放《两只老虎》完整教程(附代码与乐理速成)
用51单片机驱动无源蜂鸣器演奏《两只老虎》全流程解析 第一次听到单片机播放音乐时,那种"机器唱歌"的奇妙感至今难忘。作为电子爱好者入门必备的趣味项目,用蜂鸣器演奏音乐不仅能巩固定时器、中断等核心知识,更能将枯燥的理论转化为…...
防火墙旁挂模式实战:用华为模拟器ENSP搭建VRF+OSPF实验环境(保姆级)
华为eNSP防火墙旁挂模式全实战:从VRF设计到流量抓包分析 在企业网络架构中,防火墙的部署方式直接影响网络安全策略的实施效果。旁挂模式作为一种灵活部署方案,既能实现流量精细化管控,又避免了单点故障风险。本文将带您使用华为eN…...
OpenClaw任务编排:GLM-4.7-Flash驱动复杂工作流
OpenClaw任务编排:GLM-4.7-Flash驱动复杂工作流 1. 为什么需要任务编排? 去年我接手了一个重复性极高的数据整理工作——每周需要从十几个不同来源收集数据,清洗后生成可视化报告。最初尝试用Python脚本自动化,但随着需求变化&a…...
别再死记硬背了!用Python和SymPy库5分钟可视化理解泰勒公式的逼近过程
用Python动态可视化泰勒公式:5行代码理解多项式逼近本质 数学公式的抽象性常常成为学习者的障碍,尤其是泰勒公式这种涉及无限逼近概念的内容。传统的静态图示和理论推导虽然严谨,却难以直观展示"以直代曲"的动态过程。本文将用Pyth…...
d-id AI studio会员值得买吗?实测3大核心功能与免费版对比
d-id AI studio会员深度评测:三大核心功能实测与免费版差异全解析 在数字内容创作领域,AI视频工具正掀起一场革命。作为行业新锐,d-id AI studio凭借其独特的面部动画技术,让普通用户也能轻松制作专业级动态视频。但对于已经体验…...
YOLOv11分割模型实战:用C++和ONNXRuntime解析‘output0’和‘output1’双输出,实现像素级颜色分析
YOLOv11分割模型实战:C与ONNXRuntime双输出解析与像素级颜色分析 在计算机视觉领域,目标检测与实例分割技术的结合正成为工业应用的新标准。YOLOv11作为YOLO系列的最新成员,不仅延续了其高效检测的特性,更通过双输出结构实现了精准…...
MySQL高手第三章
从磁盘读取数据页到Buffer Pool的时候,free链表有什么用?我们怎么知道那些缓存是空闲的?当我们数据库运行起来的时候,肯定会不断的做增删改查,将磁盘上读取一个一个数据页放入Buffer Pool中对应的缓存页里去但是从磁盘…...
