EmguCV学习笔记 C# 11.6 图像分割

 版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。

EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。

教程VB.net版本请访问:EmguCV学习笔记 VB.Net 目录-CSDN博客

教程C#版本请访问:EmguCV学习笔记 C# 目录-CSDN博客

笔者的博客网址:https://blog.csdn.net/uruseibest

教程配套文件及相关说明以及如何获得pdf教程和代码,请移步:EmguCV学习笔记

学习VB.Net知识,请移步: vb.net 教程 目录_vb中如何用datagridview-CSDN博客

 学习C#知识,请移步:C# 教程 目录_c#教程目录-CSDN博客

11.6 图像分割

11.6.1 语义分割Fcn

FCN(Fully Convolutional Network)是一种流行的语义分割算法,它通过将传统的卷积神经网络转化为全卷积网络来实现像素级别的语义分割,将输入图像传入网络中,得到每个像素的标签,并根据标签来分割出不同的物体。FCN在语义分割任务中表现优秀,可以实现像素级别的精细分割,被广泛应用于自动驾驶、智能监控等领域。

【代码位置:frmChapter11】Button5_Click、getColorTable、showColorTable

        //语义分割fcn

        private void Button5_Click(object sender, EventArgs e)

        {

            //对象分类,object_detection_classes_pascal_voc.txt文件提供了21类对象(含background

            string[] classnames = System.IO.File.ReadAllLines("C:\\learnEmgucv\\fcn\\object_detection_classes_pascal_voc.txt");

            //获得输出颜色表

            Bgr[] colorTable = getColorTable();

            //显示颜色表及对应对象名称

            showColorTable(classnames, colorTable);

            //需要测试的图像文件

            Mat m = new Mat("C:\\learnEmgucv\\dnntest1.jpg", ImreadModes.Color);

            Single hm = m.Height;

            Single wm = m.Width;

            Net net;

            net = DnnInvoke.ReadNetFromCaffe("C:\\learnEmgucv\\fcn\\fcn8s-heavy-pascal.prototxt",

                                             "C:\\learnEmgucv\\fcn\\fcn8s-heavy-pascal.caffemodel"

                                            );

            Mat mcopy = new Mat();

            CvInvoke.Resize(m, mcopy, new Size(500, 500));

            Mat blob = DnnInvoke.BlobFromImage(mcopy, 1, new Size(500, 500),

                                       new MCvScalar(0,0,0), false, false);

            net.SetInput(blob);

            Mat mout = new Mat();

            mout = net.Forward();

            Single[,,,] fout;

            fout = (Single[,,,])mout.GetData();

            //通道数=21,即21类对象

            int chan = fout.GetLength(1);

            //高度=500

            int row = fout.GetLength(2);

            //宽度=500

            int col = fout.GetLength(3);

            //记录21个通道对应坐标点的最大值

            Matrix<Single> matrMaxValue = new Matrix<Single>(new Size(row, col));

            matrMaxValue.SetZero();

            记录对应通道号

            //Matrix<Single> matrMaxChan = new Matrix<Single>(new Size(row, col));

            //matrMaxChan.SetZero();

            //记录对应颜色

            Image<Bgr, byte> imgOut = new Image<Bgr, byte>(col, row);

            imgOut.SetZero();

            //遍历21个通道

            for (int c = 0; c < chan; c++)

                for (int h = 0; h < row; h++)

                    //遍历高度和宽度,获得对应坐标的值

                    for (int w = 0; w < col; w++)

                        //比较最大值

                        if (fout[0, c, h, w] > matrMaxValue[h, w])

                        {

                            //取得最大值

                            matrMaxValue[h, w] = fout[0, c, h, w];

                            取得通道号

                            //matrMaxChan[h, w] = c;

                            //最重要的是获取通道对应颜色表的值

                            imgOut[h, w] = colorTable[c];

                        }

            //显示输出的图像

            //ImageBox1.Image = imgOut.Mat;

            //设置掩膜

            Mat mask = new Mat();

            mask = imgOut.Mat;

            //掩膜大小必须和源图像一致

            CvInvoke.Resize(mask, mask, m.Size);

            //将上面的输出图像和源图像叠加

            Mat mFinalOut = new Mat();

            CvInvoke.AddWeighted(m, 0.3, mask, 0.7, 0, mFinalOut);

            ImageBox1.Image = mFinalOut;

        }

       //为了更好地观察,这里没有使用随机颜色

        private Bgr[] getColorTable()

        {

            Bgr[] newColors = new Bgr[21];

            newColors[0] = new Bgr(0, 0, 0);        //background

            newColors[1] = new Bgr(128, 0, 0);      //aeroplane

            newColors[2] = new Bgr(0, 128, 0);      //bicycle

            newColors[3] = new Bgr(128, 128, 0);    //bird

            newColors[4] = new Bgr(0, 0, 128);      //boat

            newColors[5] = new Bgr(128, 0, 128);    //bottle

            newColors[6] = new Bgr(0, 128, 128);    //bus

            newColors[7] = new Bgr(128, 128, 128);  //car

            newColors[8] = new Bgr(255, 0, 0);     //cat

            newColors[9] = new Bgr(0, 255, 0);     //chair

            newColors[10] = new Bgr(0, 0, 255);     //cow

            newColors[11] = new Bgr(255, 255, 0);   //diningtable

            newColors[12] = new Bgr(64, 0, 128);    //dog

            newColors[13] = new Bgr(192, 0, 128);   //horse

            newColors[14] = new Bgr(64, 128, 128);  //motorbike

            newColors[15] = new Bgr(192, 128, 128); //person

            newColors[16] = new Bgr(0, 64, 0);     //pottedplant

            newColors[17] = new Bgr(128, 64, 64);   //sheep

            newColors[18] = new Bgr(0, 192, 0);     //sofa

            newColors[19] = new Bgr(128, 192, 0);   //train

            newColors[20] = new Bgr(0, 64, 128);    //tvmonitor

            return newColors;

        }

        //显示颜色表及对象名称

        //参数1:对象名称的字符串数组

        //参数2bgr颜色数组

        private void showColorTable(string[] names, Bgr[] colors)

        {

            List<Mat> lstmoutV = new List<Mat>();

            for (int i = 0; i <= 20; i++)

            {

                Mat moutV = new Mat(40, 200, DepthType.Cv8U, 3);

                moutV.SetTo(new MCvScalar(colors[i].Blue, colors[i].Green, colors[i].Red));

                CvInvoke.PutText(moutV, names[i], new Point(20, 25), FontFace.HersheyTriplex, 0.4, new MCvScalar(255, 255, 255));

                lstmoutV.Add(moutV);

            }

            Mat mout = new Mat();

            //垂直方向拼接

            CvInvoke.VConcat(lstmoutV.ToArray(), mout);

            CvInvoke.Imshow("colortable", mout);

        }

输出结果如下图所示:

 

图11-4 FCN分割获得不同对象区域

11.6.2 实例分割 MASK RCNN

Mask RCNN是一种基于Faster R-CNN的实例分割算法,它是一种联合目标检测和语义分割的方法,能够同时检测图像中的对象并得到每个对象的位置、类别和像素级别的分割结果。Mask RCNN在实例分割任务中表现优秀,是目前最先进的实例分割算法之一,被广泛应用于自动驾驶、智能监控等领域。

【代码位置:frmChapter11】Button6_Click、getRadomColor

        //实例分割 mask rcnn

        private void Button6_Click(object sender, EventArgs e)

        {

            //对象分类,object_detection_classes_coco.txt文件提供了90类对象(含background

            string[] classnames;

            classnames = System.IO.File.ReadAllLines("C:\\learnEmgucv\\maskrcnn\\object_detection_classes_coco.txt");

            //需要测试的图像文件

            Mat m = new Mat("C:\\learnEmgucv\\dnntest.jpg", ImreadModes.Color);

            Single hm = m.Height;

            Single wm = m.Width;

            Net net;

            net = DnnInvoke.ReadNetFromTensorflow("C:\\learnEmgucv\\maskrcnn\\frozen_inference_graph.pb",

                                 "C:\\learnEmgucv\\maskrcnn\\mask_rcnn_inception_v2_coco_2018_01_28.pbtxt"

                                  );

            Mat mcopy = new Mat();

            mcopy = m.Clone();

            Mat blob;

            blob = DnnInvoke.BlobFromImage(mcopy, 1, new Size(500, 500),

                                           new MCvScalar(0, 0, 0), false, false);

            net.SetInput(blob);

            string[] names = new string[2];

            names[0] = "detection_out_final";

            names[1] = "detection_masks";

            //返回的mout包含两个mat

            VectorOfMat mout = new VectorOfMat();

            net.Forward(mout, names);

            //第一个mat标识返回的置信度候选框,是一个四维数组

            Mat moutBox = new Mat();

            moutBox = mout[0];

            //返回维度:

            //1维:1

            //2维:1

            //3维:100100个候选置信矩形框

            //4维:70?;1:对应类别;2:置信度;3-6:候选框位置(源图像百分比)

            Single[,,,] foutBox;

            foutBox = (Single[,,,])moutBox.GetData();

            //第二个mat标识返回的掩膜,是一个四维数组   

            Mat moutMask = new Mat();

            moutMask = mout[1];

            //返回维度:

            //1维:100100个对象对应的100个掩膜

            //2维:90,对象的置信度

            //3维:15,掩膜高度

            //4维:15,掩膜宽度

            Single[,,,] foutMask;

            foutMask = (Single[,,,])moutMask.GetData();

            int maskH = 15;   //foutMask.GetLength(2)

            int maskW = 15;  //foutMask.GetLength(3)

            //新建Mat,用来在这上面绘制掩膜

            Mat mbg = new Mat(new Size(m.Width, m.Height), DepthType.Cv8U, 3);

            mbg.SetTo(new MCvScalar(0, 0, 0));

            for (int i = 0; i < 100; i++)

            {

                //置信度

                Single conf = foutBox[0, 0, i, 2];

                //当置信度满足时

                if (conf > 0.53)

                {

                    //对应检测对象的序号

                    int objID = (int)foutBox[0, 0, i, 1];

                    Single ltX = foutBox[0, 0, i, 3] * wm; //左上角X

                    Single ltY = foutBox[0, 0, i, 4] * hm; //左上角Y

                    Single rbX = foutBox[0, 0, i, 5] * wm; //右下角X

                    Single rbY = foutBox[0, 0, i, 6] * hm; //右下角Y

                    Single w = rbX - ltX; //宽度

                    Single h = rbY - ltY; //高度

                    //绘制包围矩形框

                    CvInvoke.Rectangle(m, new Rectangle((int)ltX, (int)ltY,(int) w, (int)h), new MCvScalar(0, 0, 255), 1);

                    //绘制对象名称

                    CvInvoke.PutText(m, classnames[objID], new Point((int)ltX, (int)ltY - 10), FontFace.HersheyTriplex, 0.3, new MCvScalar(255, 0, 0));

                    //开始处理掩膜

                    Mat mmask = new Mat();

                    //掩膜大小为15*15,对应foutMask最后两个维度

                    Single[,] bmask = new Single[15, 15];

                    for (int j = 0; j < 15; j++)

                        for (int k = 0; k < 15; k++)

                            bmask[j, k] = foutMask[i, objID, j, k];

                    //将数组转为Mat

                    Matrix<Single> matrmask = new Matrix<Single>(bmask);

                    mmask = matrmask.Mat;

                    //大小放大与对应包围矩形框一致

                    CvInvoke.Resize(mmask, mmask, new Size((int)w, (int)h));

                    //二值化

                    CvInvoke.Threshold(mmask, mmask, 0.3, 255, ThresholdType.Binary);

                    //由于本身是CV32F,需要处理为CV8U,才能使用FindContours

                    mmask.ConvertTo(mmask, DepthType.Cv8U);

                    //定义关注区域,当修改关注区域时,也就修改了源图像

                    Mat mRoi = new Mat(mbg, new Rectangle((int)ltX, (int)ltY, (int)w, (int)h));

                    //查找轮廓

                    VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();

                    CvInvoke.FindContours(mmask, contours, null, RetrType.External, ChainApproxMethod.ChainApproxSimple);

                    //填充轮廓

                    CvInvoke.DrawContours(mRoi, contours, -1, getRadomColor(), -1);

                }

            }

            Mat mresult = new Mat();

            //加法

            CvInvoke.AddWeighted(m, 1, mbg, 0.4, 0, mresult);

            ImageBox1.Image = mresult;

        }

        //获得随机颜色

        private MCvScalar getRadomColor()

        {

            Random rd = new Random(DateTime.Now.Millisecond);

            byte r, g, b;

            b = (byte)rd.Next(256);

            g = (byte)rd.Next(256);

            r = (byte)rd.Next(256);

            return new MCvScalar(b, g, r);

        }

输出结果如下图所示:

 

图11-5 Mask RCNN 分割得到对象区域和类别

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《微信小程序实战(2) · 组件封装》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

天津大学推出“AI学长”

B站&#xff1a;啥都会一点的研究生公众号&#xff1a;啥都会一点的研究生 AI圈又发生了啥新鲜事&#xff1f; 天津大学推出“AI 学长”海棠棠&#xff0c;全天候解答新生疑问 天津大学未来技术学院研发了名为“海棠棠”的新生智能体&#xff0c;它能够24小时不间断地为新生…

Oracle 19c异常恢复—ORA-01209/ORA-65088---惜分飞

由于raid卡bug故障,导致文件系统异常,从而使得数据库无法正常启动,客户找到我之前已经让多人分析,均未恢复成功,查看alert日志,发现他们恢复的时候尝试resetlogs库,然后报ORA-600 kcbzib_kcrsds_1错误 2024-09-15T17:07:32.55321508:00 alter database open resetlogs 2024-09-…

【iOS】push和present的区别

【iOS】push和present的区别 文章目录 【iOS】push和present的区别前言pushpop presentdismiss简单小demo来展示dismiss和presentdismiss多级 push和present的区别区别相同点 前言 在iOS开发中&#xff0c;我们经常性的会用到界面的一个切换的问题&#xff0c;这里我们需要理清…

C++11新增特性:lambda表达式、function包装器、bind绑定

一、lambda表达式 1&#xff09;、为啥需要引入lambda&#xff1f; 在c98中&#xff0c;我们使用sort对一段自定义类型进行排序的时候&#xff0c;每次都需要传一个仿函数&#xff0c;即手写一个完整的类。甚至有时需要同时实现排升序和降序&#xff0c;就需要各自手写一个类&…

信息学奥赛初赛天天练-91-CSP-S2023基础题3-编译命令、树的重心、拓扑排序、进制转换、R进制转十进制、十进制转R进制

PDF文档公众号回复关键字:20240917 2023 CSP-S 选择题 1单项选择题&#xff08;共15题&#xff0c;每题2分&#xff0c;共计30分&#xff1a;每题有且仅有一个正确选项&#xff09; 11 以下哪个命令&#xff0c;能将一个名为 main.cpp 的 C 源文件&#xff0c;编译并生成一个…

[Unity Demo]从零开始制作空洞骑士Hollow Knight第二集:通过InControl插件实现绑定玩家输入以及制作小骑士移动空闲动画

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、通过InControl插件实现绑定玩家输入二、制作小骑士移动和空闲动画 1.制作动画2.玩家移动和翻转图像3.状态机思想实现动画切换总结 前言 好久没来CSDN看看&…

利用JS数组根据数据生成柱形图

要求 <html> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document…

Python 基础 (标准库):datetime (基本日期和时间类型)

1. 官方文档 datetime --- 基本日期和时间类型 — Python 3.12.2 文档 tz — dateutil 3.9.0 documentation 2. 背景 2.1 处理时间数据的难点 计算机程序喜欢有序的、有规则的事件&#xff0c;但对于时间数据&#xff0c;其涉及的规则复杂且可能有变化&#xff0c;最典型例…

【homebrew安装】踩坑爬坑教程

homebrew官网&#xff0c;有安装教程提示&#xff0c;但是在实际安装时&#xff0c;由于待下载的包的尺寸过大&#xff0c;本地git缓存尺寸、超时时间的限制&#xff0c;会报如下错误&#xff1a; error: RPC failed; curl 92 HTTP/2 stream 5 was not closed cleanly&#xf…

2024永久激活版 Studio One 6 Pro for mac 音乐创作编辑软件 完美兼容

Studio One 6是一款功能强大的音乐制作软件&#xff0c;由PreSonus公司开发。它提供了全面的音频录制、编辑、混音和母带处理工具&#xff0c;适用于音乐制作人、音频工程师和创作人员。 Studio One 6拥有直观的用户界面&#xff0c;使用户能够快速而流畅地进行音乐创作。它采…

华为HarmonyOS地图服务 -- 如何实现地图呈现?-- HarmonyOS自学8

如何使用地图组件MapComponent和MapComponentController呈现地图&#xff0c;效果如下图所示。 MapComponent是地图组件&#xff0c;用于在您的页面中放置地图。MapComponentController是地图组件的主要功能入口类&#xff0c;用来操作地图&#xff0c;与地图有关的所有方法从此…

基于 onsemi NCV78343 NCV78964的汽车矩阵式大灯方案

一、方案描述 大联大世平集团针对汽车矩阵大灯&#xff0c;推出 基于 onsemi NCV78343 & NCV78964的汽车矩阵式大灯方案。 开发板搭载的主要器件有 onsemi 的 Matrix Controller NCV78343、LED Driver NCV78964、Motor Driver NCV70517、以及 NXP 的 MCU S32K344。 二、开…

【我的 PWN 学习手札】Fastbin Double Free

前言 Fastbin的Double Free实际上还是利用其特性产生UAF的效果&#xff0c;使得可以进行Fastbin Attack 一、Double Free double free&#xff0c;顾名思义&#xff0c;free两次。对于fastbin这种单链表的组织结构&#xff0c;会形成这样一个效果&#xff1a; 如果我们mallo…

记一次实战中对fastjson waf的绕过

最近遇到一个fastjson的站&#xff0c;很明显是有fastjson漏洞的&#xff0c;因为type这种字符&#xff0c;fastjson特征很明显的字符都被过滤了 于是开始了绕过之旅&#xff0c;顺便来学习一下如何waf 编码绕过 去网上搜索还是有绕过waf的文章&#xff0c;下面来分析一手&a…

分布式训练:(Pytorch)

分布式训练是将机器学习模型的训练过程分散到多个计算节点或设备上&#xff0c;以提高训练速度和效率&#xff0c;尤其是在处理大规模数据和模型时。分布式训练主要分为数据并行和模型并行两种主要策略&#xff1a; 1. 数据并行 (Data Parallelism) 数据并行是最常见的分布式…

【网络安全】逻辑漏洞之购买商品

未经授权,不得转载。 文章目录 正文正文 电子商务平台的核心功能,即购买商品功能。因为在这个场景下,任何功能错误都有可能对平台产生重大影响,特别是与商品价格和数量有关的问题。 将商品添加到购物车时拦截请求: 请求包的参数: 解码参数后,并没有发现价格相关的参数,…

Python(TensorFlow和PyTorch)及C++注意力网络导图

&#x1f3af;要点 谱图神经网络计算注意力分数对比图神经网络、卷积网络和图注意力网络药物靶标建模学习和预测相互作用腹侧和背侧皮质下结构手写字体字符序列文本识别组织病理学图像分析长短期记忆财务模式预测相关性生物医学图像特征学习和迭代纠正 Python注意力机制 对…

AE VM5000 Platform VarioMatch Match Network 手侧

AE VM5000 Platform VarioMatch Match Network 手侧

算法入门-贪心1

第八部分&#xff1a;贪心 409.最长回文串&#xff08;简单&#xff09; 给定一个包含大写字母和小写字母的字符串 s &#xff0c;返回通过这些字母构造成的最长的回文串 的长度。 在构造过程中&#xff0c;请注意 区分大小写 。比如 "Aa" 不能当做一个回文字符串…