C#描述-计算机视觉OpenCV(4):图像分割

news2024/11/23 10:16:57

C#描述-计算机视觉OpenCV(4):图像分割

    • 前言
    • 用 GrabCut 算法分割图像
    • 实例展示

前言

本文中如果有什么没说明的地方,大概率在前文中描述过了。
C#描述-计算机视觉OpenCV(1):基础操作
C#描述-计算机视觉OpenCV(2):图像处理
C#描述-计算机视觉OpenCV(3):重映射
上一章节我们通过波形来分析了图像,那么图像中的背景与主体在波形上会有怎样的呈现呢?

for (int k = 120; k < 400; k++)
            {
                int r = 390;
                XList4.Add(k);
                YList4.Add(img.At<Vec3b>(r, k)[1]);
                chart2.Series["Green"].Points.DataBindXY(XList4, YList4);
                XList5.Add(k);
                YList5.Add(img.At<Vec3b>(r, k)[2]);
                chart2.Series["Blue"].Points.DataBindXY(XList5, YList5);
                XList6.Add(k);
                YList6.Add(img.At<Vec3b>(r, k)[0]);
                chart2.Series["Red"].Points.DataBindXY(XList6, YList6);
                img.At<Vec3b>(r, k)[0] = 0;
                img.At<Vec3b>(r, k)[1] = 0;
                img.At<Vec3b>(r, k)[2] = 0;//检测线标记
            }

我们标记一条检测线并示波
在这里插入图片描述
色彩波形结果:
在这里插入图片描述

这种差别以为着我们可以通过数值的变化来捕捉图片中的物体,并且做出分割。

用 GrabCut 算法分割图像

物体通常有自己特有的颜色,通过识别颜色接近的区域,通常可以提取出这些颜色。OpenCV 提供了一种常用的图像分割算法,即 GrabCut 算法。GrabCut 算法比较复杂,计算量也很大,但结果通常很精确。如果要从静态图像中提取前景物体(例如从图像中剪切一个物体,并粘贴到另一幅图像),最好采用GrabCut 算法。
算法参数模型:
cv::Mat result; // 分割结果(四种可能的值)
cv::Mat bgModel,fgModel; // 模型(内部使用)
// GrabCut 分割算法
cv::grabCut(
image, // 输入图像
mask, // 分割结果
rectangle, // 包含前景的矩形
bgModel,fgModel, // 模型
X, // 迭代次数
cv::GC_INIT_WITH_RECT // 使用矩形
);
首先我们开出需要的模型:

Mat mask = new Mat();
Mat res = new Mat();
Mat bgM = new Mat();
Mat fgM = new Mat();

然后我们定义一个检测矩形区域:

Rect rectangle;
rectangle = new Rect(int X,int Y,int Width,int Height);

然后我们可以代入一个图像,使用GrabCut()方法,

Cv2.GrabCut(image, mask, rectangle, bgM, fgM, 5, GrabCutModes.InitWithRect);

并获得一个结果Mat类 mask。需要注意:这个mask可不代表分割完成的结果。
我们在函数的中用 InitWithRect 标志作为最后一个参数,表示将使用
带边框的矩形模型。矩形中输入/输出的分割图像可以是以下四个值之一。
1.GC_BGD:这个值表示明确属于背景的像素(例如本例中矩形之外的像素)。
2.GC_FGD:这个值表示明确属于前景的像素(本例中没有这种像素)。
3.GC_PR_BGD:这个值表示可能属于背景的像素。
4.GC_PR_FGD:这个值表示可能属于前景的像素(即本例中矩形之内像素的初始值)
也就是说我们的mask是一个判断是否为主题的结果的矩阵,我们还需要来操作读取才能完成图像分割,那么具体该如何操作呢?

实例展示

原图如下:
在这里插入图片描述
我们选取区域(200, 45, 150, 400)来做切割,这里面主体与背景非常清晰。

public void ColorDetector(Mat image)
        {
            Mat mask = new Mat();
            Mat res = new Mat();
            Mat bgM = new Mat();
            Mat fgM = new Mat();
            Rect rectangle;
            
            rectangle = new Rect(200, 45, 150, 400);
            Cv2.GrabCut(image, mask, rectangle, bgM, fgM, 5, GrabCutModes.InitWithRect);

            Mat result = new Mat(mask.Rows, mask.Cols, MatType.CV_8UC1);
            for (int i = 0; i < mask.Rows; i++)
            {
                for (int j = 0; j < mask.Cols; j++)
                {
                    byte v = mask.Get<byte>(j, i);
                    switch (v)
                    {
                        case 0:
                            result.Set<byte>(j, i, 0);
                            break;
                        case 1:
                            result.Set<byte>(j, i, 255);
                            break;
                        case 2:
                            result.Set<byte>(j, i, 50);
                            break;
                        case 3:
                            result.Set<byte>(j, i, 200);
                            break;
                    }
                }
            }
            Cv2.ImShow("grab", result);
        }

我们划分出四个结果类型的区域,来看看分割的是否准确:
在这里插入图片描述
通过色块可以看到,我们还是切割出来了的,找到我们需要的色块类型,进行还原,并将其他色块统一:

for (int i = 0; i < mask.Rows; i++)
            {
                for (int j = 0; j < mask.Cols; j++)
                {
                    byte v = mask.Get<byte>(j, i);
                    switch (v)
                    {
                        case 0:
                            result.Set<byte>(j, i, 0);
                            
                            break;
                        case 1:
                            result.Set<byte>(j, i, 0);
                           
                            break;
                        case 2:
                          
                            result.Set<byte>(j, i, 0);
                            break;
                        case 3:
                            result.At<Vec3b>(j, i)[0] = image.At<Vec3b>(j, i)[0];
                            result.At<Vec3b>(j, i)[1] = image.At<Vec3b>(j, i)[1];
                            result.At<Vec3b>(j, i)[2] = image.At<Vec3b>(j, i)[2];
                            //result.Set<byte>(j, i, 200);
                            break;
                    }
                }
            }

在这里插入图片描述
分割成功!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1640999.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第十五届蓝桥杯省赛大学B组(c++)

很幸运拿了辽宁赛区的省一,进入6月1号的国赛啦... 这篇文章主要对第十五届省赛大学B组(C)进行一次完整的复盘,这次省赛2道填空题6道编程题: A.握手问题 把握手情景看成矩阵: 粉色部分是7个不能互相捂手的情况 由于每个人只能和其他人捂手, 所以黑色情况是不算的 1和2握手2和…

快速掌握Element-Ul,构建高效网页应用【AI写作】

首先&#xff0c;这篇文章是基于笔尖AI写作进行文章创作的&#xff0c;喜欢的宝子&#xff0c;也可以去体验下&#xff0c;解放双手&#xff0c;上班直接摸鱼~ 按照惯例&#xff0c;先介绍下这款笔尖AI写作&#xff0c;宝子也可以直接下滑跳过看正文~ 笔尖Ai写作&#xff1a;…

JavaScript继承的方法和优缺点

原型链继承 让一个构造函数的原型是另一个类型的实例&#xff0c;那么这个构造函数new出来的实例就具有该实例的属性。 优点&#xff1a; 写法方便简洁&#xff0c;容易理解。 缺点&#xff1a; 在父类型构造函数中定义的引用类型值的实例属性&#xff0c;会在子类型原型上…

逻辑回归实战 -- 是否通过考试

http://链接: https://pan.baidu.com/s/1-uy-69rkc4WjMpPj6iRDDw 提取码: e69y 复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦 数据集下载链接 这是个二分类问题&#xff0c;通过x1,x2两个指标得出是否通过考试的结论。 逻辑回归的激活函数是sigmoid函数&…

STM32单片机实战开发笔记-EXIT外部中断检测

嵌入式单片机开发实战例程合集&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/11av8rV45dtHO0EHf8e_Q0Q?pwd28ab 提取码&#xff1a;28ab EXIT模块测试 功能描述 外部中断/事件控制器由19个产生事件/中断要求的边沿检测器组成。每个输入线可以独立地配置输入类型&a…

P9422 [蓝桥杯 2023 国 B] 合并数列

P9422 [蓝桥杯 2023 国 B] 合并数列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 用队列即可 当两个队列队首&#xff1a;a b &#xff0c;弹出 当a < b&#xff0c;把a加给其后一个元素&#xff0c;弹出a 当b < a&#xff0c;把b加给其后一个元素&#xff0c;弹出…

Eclipse 开创性地集成 Neon Stack,将 EVM 兼容性带到 SVM 网络

2024年5月2日&#xff0c;全球——在塑造区块链网络的战略联盟的过程中&#xff0c;Eclipse 通过集成 Neon EVM 核心团队开发的技术堆栈 Neon Stack&#xff0c;成为首个打破 EVM-SVM 兼容性障碍的生态。 Eclipse 旨在通过结合以太坊和 Solana 的最佳特性&#xff0c;来重构区…

2024年钉钉群直播回放如何永久保存

工具我已经打包好了&#xff0c;有需要的自己取一下 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;1234 --来自百度网盘超级会员V10的分享 1.首先解压好我给大家准备好的压缩包 2.再把逍遥一仙下载器压缩包也解压一下 3.打开逍遥一仙下载器文件夹里面的M3U8…

华为云耀云服务器开放端口

博客主页&#xff1a;花果山~程序猿-CSDN博客 关注我一起学习&#xff0c;一起进步&#xff0c;一起探索编程的无限可能吧&#xff01;让我们一起努力&#xff0c;一起成长&#xff01; 目录 一.华为云控制台开放端口 寻找到安全组信息 2. 添加开放的端口信息 3. 检查是否成…

常用AI工具分享 + IDEA内使用通义灵码

引言 随着人工智能技术的飞速发展&#xff0c;AI工具已经渗透到我们日常生活和工作的各个领域&#xff0c;带来了前所未有的便利。现在我将分享一下常用的AI工具&#xff0c;以及介绍如何在IDEA中使用通义灵码。 常用AI工具 1. 通义灵码 (TONGYI Lingma) - 由阿里云开发的智能…

STM32的TIM输入捕获和PWMI详解

系列文章目录 STM32单片机系列专栏 C语言术语和结构总结专栏 文章目录 1. IC输入捕获 2. 频率测量 3. 主模式、从模式、触发源选择 4. 输入捕获基本结构 5. PWMI模式 6. 代码示例 6.1 PWM.c 6.2 PWM.h 6.3 IC.c 6.4 IC.h 6.5 完整工程文件 输出比较可以看下面这篇…

Covalent Network(CQT)为 Arbitrum 生态提供 250 万美元的资助,以促进 Web3 的创新与发展

Covalent Network&#xff08;CQT&#xff09;作为 Web3 领先的“数据可用性”层&#xff0c;宣布将提供 250 万美元的资金以支持 Arbitrum 生态项目&#xff0c;包括 Arbitrum One、Nova、Orbit 或 Stylus。此举旨在通过提供资源和帮助&#xff0c;推动利用 Arbitrum 网络上 C…

华为机考入门python3--(20)牛客20- 密码验证合格程序

分类&#xff1a;字符串 知识点&#xff1a; 遍历字符串的每个字符 for char in my_str: 可以直接比较字符范围 a < char < z 列表统计元素个数 my_list.count(elem) 寻找子串 my_str.find(sub_str) 题目来自【牛客】 import re import sysdef check_…

信息泄露.

一&#xff0c;遍历目录 目录遍历&#xff1a;没有过滤目录相关的跳转符号&#xff08;例如&#xff1a;../&#xff09;&#xff0c;我们可以利用这个目录找到服务器中的每一个文件&#xff0c;也就是遍历。 tipe&#xff1a;依次点击文件就可以找到flag 二&#xff0c;phpi…

AI视频教程下载:零代码创建AI智能体、AI Agents和ChatGPT的Gpts

这门课程专注于提示工程的掌握&#xff0c;教你以精确的方式引导GPT&#xff0c;利用它们的生成能力产生卓越的AI驱动结果。一步一步地&#xff0c;你将学会创建多样化的GPT军团——每个都设计来满足特定的专业需求。 从提供个性化职业变更指导的职业教练AI&#xff0c;到以惊…

uniapp 监听APP切换前台、后台插件 Ba-Lifecycle

监听APP切换前台、后台 Ba-Lifecycle 简介&#xff08;下载地址&#xff09; Ba-Lifecycle 是一款uniapp监听APP切换前台、后台的插件&#xff0c;简单易用。 截图展示 也可关注博客&#xff0c;实时更新最新插件&#xff1a; uniapp 常用原生插件大全 使用方法 在 script…

可视化大屏应用场景:智慧安防,保驾护航

hello&#xff0c;我是大千UI工场&#xff0c;本篇分享智慧安防的大屏设计&#xff0c;关注我们&#xff0c;学习N多UI干货&#xff0c;有设计需求&#xff0c;我们也可以接单。 实时监控与预警 可视化大屏可以将安防系统中的监控画面、报警信息、传感器数据等实时展示在大屏上…

k8s笔记 | Ingress

安装Ingress 添加helm创库 Installation Guide - Ingress-Nginx Controller Ingress | Kubernetes 下载包 将 文件helm 放到 /usr/local/bin/ 并给到执行权限 # 添加可执行权限 chmod ux helm # 测试是否能运行 helm version# 结果 version.BuildInfo{Version:"v3.14…

快速批量重命名文件(夹)

首先&#xff0c;需要用到的这个工具&#xff1a; 度娘网盘 提取码&#xff1a;qwu2 蓝奏云 提取码&#xff1a;2r1z 我这里处理这4个文本&#xff0c;实际可以处理任意数量的文本和文件夹 1、打开工具&#xff0c;进入文件批量复制版块 2、点击“重命名” 3、把要重命名的…

从0开始学习制作一个微信小程序 学习部分(6)组件与事件绑定

系列文章目录 学习篇第一篇我们讲了编译器下载&#xff0c;项目、环境建立、文件说明与简单操作&#xff1a;第一篇链接 第二、三篇分析了几个重要的配置json文件&#xff0c;是用于对小程序进行的切换页面、改变图标、控制是否能被搜索到等的操作第二篇链接、第三篇链接 第四…