图像分割-Grabcut法(C#)
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。
本文的VB版本请访问:图像分割-Grabcut法-CSDN博客
GrabCut是一种基于图像分割的技术,它可以用于将图像中的前景和背景分离。在实现中,GrabCut算法通常需要使用高斯混合模型(GMM)来建立前景和背景的概率分布,以便更好的估计像素的标签。同时,还需要考虑如何处理边界处的像素,以避免边界处的像素被错误地分类。GrabCut算法在图像分割中有着广泛的应用,例如人像分割、物体抠图等。
EmguCV使用CvInvoke.GrabCut方法来执行GrabCut算法,该方法声明如下:
public static void GrabCut(
IInputArray img,
IInputOutputArray mask,
Rectangle rect,
IInputOutputArray bgdModel,
IInputOutputArray fgdModel,
int iterCount,
GrabcutInitType type
)
参数说明:
- img:输入输出的图像,必须是三通道彩色图像。
- mask:指定的掩码图像,必须是单通道灰度图像,并且与输入图像具有相同的尺寸。可以传入0-3的值,分别为:0表示明显为背景的像素、1表示冥相位前景的像素、2表示可能为背景的像素、3表示可能为前景的像素。
- rect:指定的矩形框,用于定位大概率可能为前景目标的位置。
- bgdModel:背景模型,必须是单通道浮点型Mat。
- fgdModel:前景模型,必须是单通道浮点型Mat。
- iterCount:迭代次数,用于控制算法的收敛性。
- type:GrabCut算法初始化类型,可以选择GrabCutInitType.WithRect或GrabCutInitType.WithMask,分别表示根据提供的矩形初始化或根据掩码初始化。
该方法没有返回值,而是直接在mask图像上进行前景分割操作,最终获得的mask包含0-3的值,含义如参数中说明。
//Grabcut法 private void Button5_Click(object sender, EventArgs e){Mat m = new Mat("C:\\learnEmgucv\\tower.jpg", ImreadModes.AnyColor);Mat result = new Mat();Mat bg = new Mat();Mat fg = new Mat();Rectangle rect = new Rectangle(80, 30, 680, 450);CvInvoke.GrabCut(m, result, rect, bg, fg, 1, GrabcutInitType.InitWithRect);//输出的result只有4个值://0:确定背景//1:确定前景//2:可能背景//3:可能前景//演示框选范围CvInvoke.Rectangle(m, rect, new MCvScalar(255, 255, 255), 1);ImageBox1.Image = m;//标记区域Matrix<byte> matr = new Matrix<byte>(result.Rows, result.Cols);result.CopyTo(matr);for (int i = 0; i < matr.Cols; i++){for (int j = 0; j < matr.Rows; j++){//将确定背景和可能背景标记为0,否则为255if (matr[j, i] == 0 || matr[j, i] == 2)matr[j, i] = 0;elsematr[j, i] = 255;}}Mat midm = new Mat();midm = matr.Mat;//显示标记的图像CvInvoke.Imshow("midm", midm);//灰度转为彩色Mat midm1 = new Mat();CvInvoke.CvtColor(midm, midm1, ColorConversion.Gray2Bgr);Mat mout = new Mat();//And运算CvInvoke.BitwiseAnd(m, midm1, mout);CvInvoke.Imshow("mout", mout);}
输出结果如下图所示:

图8-5 Grabcut法分离前景
//Grabcut法 private void Button6_Click(object sender, EventArgs e){Mat m = CvInvoke.Imread("C:\\learnEmgucv\\tower.jpg", ImreadModes.Color);Mat result = new Mat();Mat bg = new Mat();Mat fg = new Mat();Rectangle rect = new Rectangle(80, 30, 680, 450);CvInvoke.GrabCut(m, result, rect, bg, fg, 5, GrabcutInitType.InitWithRect);Image<Bgr, byte> src = m.ToImage<Bgr, byte>();Image<Bgr, byte> dst = new Image<Bgr, byte>(new Size(src.Width, src.Height));Image<Gray, byte> mask = result.ToImage<Gray, byte>();//直接操作Image像素点for (int i = 0; i < src.Rows; i++){for (int j = 0; j < src.Cols; j++){//如果是确定前景和可能前景,直接保留原像素点颜色,否则为黑色if (mask.Data[i, j, 0] == 1 || mask.Data[i, j, 0] == 3){dst.Data[i, j, 0] = src.Data[i, j, 0];dst.Data[i, j, 1] = src.Data[i, j, 1];dst.Data[i, j, 2] = src.Data[i, j, 2];}else{dst.Data[i, j, 0] = 0;dst.Data[i, j, 1] = 0;dst.Data[i, j, 2] = 0;}}}ImageBox1.Image = dst;}
输出结果如下图所示:

图8-6 Grabcut法分离前景
//标记为确定前景,这里使用InitWithMask 参数private void Button7_Click(object sender, EventArgs e){Mat m = new Mat("c:\\learnEmgucv\\lena.jpg", ImreadModes.AnyColor);Mat mask = new Mat();Mat bg = new Mat();Mat fg = new Mat();Rectangle rect = new Rectangle(80, 30, 340, 480);//使用前景为全白色Mat m1 = new Mat("c:\\learnEmgucv\\lena_fillwhite.jpg", ImreadModes.Grayscale);Mat mask1 = new Mat();//二值化CvInvoke.Threshold(m1, mask1, 250, 1, ThresholdType.Binary);CvInvoke.Rectangle(m, rect, new MCvScalar(255, 255, 255), 1);//标记之后再调用GrabCut,使用InitWithMask参数CvInvoke.GrabCut(m, mask1, rect, bg, fg, 2, GrabcutInitType.InitWithMask);Matrix<byte> matrx = new Matrix<byte>(mask1.Rows, mask1.Cols);mask1.CopyTo(matrx);for (int i = 0; i < matrx.Cols; i++)for (int j = 0; j < matrx.Rows; j++)if (matrx[i, j] == 0 || matrx[i, j] == 2)matrx[i, j] = 0;elsematrx[i, j] = 255;Mat midm2 = new Mat();midm2 = matrx.Mat;Mat midm1 = new Mat();CvInvoke.CvtColor(midm2, midm1, ColorConversion.Gray2Bgr);Mat mout = new Mat();CvInvoke.BitwiseAnd(m, midm1, mout);CvInvoke.Imshow("mout", mout);}
输出结果如下图所示:

图8-7 Grabcut法分离前景
由于.net平台下C#和vb.NET很相似,本文也可以为C#爱好者提供参考。
学习更多vb.net知识,请参看vb.net 教程 目录
相关文章:
图像分割-Grabcut法(C#)
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 本文的VB版本请访问:图像分割-Grabcut法-CSDN博客 GrabCut是一种基于图像分割的技术,它可以用于将图像中的…...
C# WPF上位机开发(Web API联调)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 很多时候,客户需要开发的不仅仅是一个上位机系统,它还有其他很多配套的系统或设备,比如物流小车、立库、数字孪…...
c语言:用结构体求平均分|练习题
一、题目 用c语言的结构体,求4位学生成绩的平均分 如图: 二、代码截图【带注释】 三、源代码【带注释】 #include <stdio.h> float aver();//声明平均分函数 void printScore();//声明打印函数 //设置结构体, struct student { …...
echarts 仪表盘进度条 相关配置
option {series: [{type: gauge,min: 0,//最大值max: 100, //最小值startAngle: 200,//仪表盘起始角度。圆心 正右手侧为0度,正上方为90度,正左手侧为180度。endAngle: -20,//仪表盘结束角度splitNumber: 100, //仪表盘刻度的分割段数itemStyle: {color…...
Simpy:Python之离散时间序列仿真
Simpy:Python之离散时间序列仿真 文章目录 Simpy:Python之离散时间序列仿真简介基本使用语法简单案例在数据中心中的应用案例 简介 下载地址网站: https://pypi.org/project/simpy/ 有关教程网站: https://simpy.readthedocs.…...
连接GaussDB(DWS)报错:Invalid or unsupported by client SCRAM mechanisms
用postgres方式连接GaussDB(DWS)报错:Invalid or unsupported by client SCRAM mechanisms 报错内容 [2023-12-27 21:43:35] Invalid or unsupported by client SCRAM mechanisms org.postgresql.util.PSQLException: Invalid or unsupported by client SCRAM mec…...
汽车标定技术(十四)--标定数据固化方法简介
目录 1.标定数据固化方法 1.1 基于XCP固化 1.2 基于UDS固化 2. 具体实现形式 2.1 CAN...
2024年关键技术发展战略趋势前瞻
技术趋势在不断变化,但总的趋势是技术日益深入人类生活的方方面面,这些趋势可能会对未来的科技发展和人类生活产生深远影响,以下是预计今年将塑造未来的一些关键技术趋势。 更多的人将采用人工智能和机器学习 人工智能(AI)和机器学习(ML)不…...
Java程序设计——GUI设计
一、目的 通过用户图形界面设计,掌握JavaSwing开发的基本方法。 二、实验内容与设计思想 实验内容: 课本验证实验: Example10_6 图 1 Example10_7 图 2 图 3 Example10_15 图 4 设计思想: ①学生信息管理系统:…...
three.js Raycaster(鼠标点击选中模型)
效果: 代码: <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red"></div><div class"box-right"…...
Springboot整合RocketMQ 基本消息处理
目录 1. 同步消息 2. 异步消息 3. 单向消息 4. 延迟消息 5. 批量消息 6. 顺序消息 7. Tag过滤 导入依赖 <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId></dependency> …...
红外传感器深入解析
引言 宇宙间的任何物体只要其温度超过零度就能产生红外辐射,事实上同可见光一样,其辐射能够进行折射和反射,这样便产生了红外技术,利用红外光探测器因其独有的优越性而得到广泛的重视,并在军事和民用领域得到了广泛…...
18、Kubernetes核心技术 - InitContainer(初始化容器)
目录 一、概述 二、使用InitContainer 一、概述 InitContainer即初始化容器,是 K8S官方为我们提供的一个可以用来判断环境是否已经满足运行 Pod 应用前所需要的条件。 比如我们有一个应用,需要部署到Tomcat环境,那么在部署这个应用Pod之前…...
electron进程通信之预加载脚本和渲染进程对主进程通信
主进程和预加载脚本通信 主进程 mian,js 和预加载脚本preload.js,在主进程中创建预加载脚本, const createWindow () > {// Create the browser window.const mainWindow new BrowserWindow({width: 300,height: 300,// 指定预加载脚本webPreferences: {preload: path.j…...
如何有效使用 .gitignore 文件
在任何使用 Git 的软件项目中,.gitignore 文件都是一个必不可少的工具。它帮助开发者定义哪些文件和目录应该被 Git 忽略,从而保持代码库的整洁和管理的简便性。 什么是 .gitignore? .gitignore 文件是一个文本文件,您可以在其中指…...
大数据毕设分享 flink大数据淘宝用户行为数据实时分析与可视化
文章目录 0 前言1、环境准备1.1 flink 下载相关 jar 包1.2 生成 kafka 数据1.3 开发前的三个小 tip 2、flink-sql 客户端编写运行 sql2.1 创建 kafka 数据源表2.2 指标统计:每小时成交量2.2.1 创建 es 结果表, 存放每小时的成交量2.2.2 执行 sql &#x…...
大语言模型训练数据集
大语言模型的数据集有很多,以下是一些常用的: - 中文维基百科:这是一个包含大量中文文本的数据集,可用于训练中文语言模型。 - 英文维基百科:这是一个包含大量英文文本的数据集,可用于训练英文语言模型。 …...
python的课后练习总结4(while循环)
for循环用于针对序列中的每个元素的一个代码块。 while循环是不断的运行,直到指定的条件不满足为止。 while 条件: 条件成立重复执行的代码1 条件成立重复执行的代码2 …….. i 1while i < 5:print(i)i i 11、使用wh…...
Flink Connector 开发
Flink Streaming Connector Flink是新一代流批统一的计算引擎,它需要从不同的第三方存储引擎中把数据读过来,进行处理,然后再写出到另外的存储引擎中。Connector的作用就相当于一个连接器,连接Flink计算引擎跟外界存储系统。Flin…...
Golang leetcode707 设计链表 (链表大成)
文章目录 设计链表 Leetcode707不使用头节点使用头节点 推荐** 设计链表 Leetcode707 题目要求我们通过实现几个方法来完成对链表的各个操作 由于在go语言中都为值传递,(注意这里与值类型、引用类型的而区别),所以即使我们直接在…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...
React核心概念:State是什么?如何用useState管理组件自己的数据?
系列回顾: 在上一篇《React入门第一步》中,我们已经成功创建并运行了第一个React项目。我们学会了用Vite初始化项目,并修改了App.jsx组件,让页面显示出我们想要的文字。但是,那个页面是“死”的,它只是静态…...
用 FFmpeg 实现 RTMP 推流直播
RTMP(Real-Time Messaging Protocol) 是直播行业中常用的传输协议。 一般来说,直播服务商会给你: ✅ 一个 RTMP 推流地址(你推视频上去) ✅ 一个 HLS 或 FLV 拉流地址(观众观看用)…...
