EMGU中的机器学习算法之:EM算法

本文档介绍了在EMGU 3.4.1版本中使用EM算法进行机器学习时遇到的问题。由于官方文档中的方法已更新,无法直接复现例程。作者通过参考OpenCV的EM算法,修改了源码并成功实现了EM算法。测试过程中发现,直接使用`EM.Train`方法无法得到正确的样本分类结果,因此选择分开调用`EM.TrainE`和`EM.TrainM`方法进行训练。最终,作者展示了算法运行后的样本点分布图像。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

EMGU官方文档中有几种机器学习的案例,但是由于EMGU算法跟随OpenCV算法在升级,官方文档中Expectation-Maximization in CSharp描述的EM算法中多个方法已经重写(弃用),使用较高版本的EMGU并不能复现例程。本文参考OpenCv中的EM算法,修改了部分源码并测试通过。


一、测试环境

  • EMGU版本:3.4.1
  • .NetFrameWork:4.7.1

二、使用步骤

1.引入库

using Emgu.CV;
using Emgu.CV.ML;
using Emgu.CV.Structure;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

2.创建控制台程序

基础方法:

		/// <summary>
        /// 机器学习之EM算法,基础
        /// </summary>
        private static void EmBase()
        {
            int N = 4; //number of clusters
            int N1 = (int)Math.Sqrt((double)4);
            //定义四种颜色,每一类用一种颜色表示
            Bgr[] colors = new Bgr[] {
                    new Bgr(0, 0, 255),
                    new Bgr(0, 255, 0),
                    new Bgr(255, 255, 0),
                    new Bgr(255, 0, 255)};

            int nSamples = 100;//100个样本点

            Matrix<float> samples = new Matrix<float>(nSamples, 2);//样本矩阵,100行2列,即100个坐标点 
            Matrix<Int32> labels = new Matrix<int>(nSamples, 1); //标注结果,不需要事先知道
            Image<Bgr, Byte> img = new Image<Bgr, byte>(500, 500);//待测数据,每一个坐标点为一个待测数据
            Matrix<float> sample = new Matrix<float>(1, 2);
            Matrix<float> means0 = new Matrix<float>(N, 2);//储存初始化均值
            Matrix<float> probs0 = new Matrix<float>(nSamples, 1); //输出一个矩阵,里面包含每个隐性变量的后验概率
            CvInvoke.cvReshape(samples.Ptr, samples.Ptr, 2, 0);
            //循环生成四个类别样本数据,共样本100个,每类样本25个
            for (int i = 0; i < N; i++)
            {
                Matrix<float> rows = samples.GetRows(i * nSamples / N, (i + 1) * nSamples / N, 1);
                double scaleX = ((i % N1) + 1.0) / (N1 + 1);
                double scaleY = ((i / N1) + 1.0) / (N1 + 1);
                //设置均值
                MCvScalar mean = new MCvScalar(scaleX * img.Width, scaleY * img.Height);
                Console.WriteLine($"mean = {mean.V0}");
                //设置标准差
                MCvScalar sigma = new MCvScalar(30, 30);
                Console.WriteLine($"sigma = {sigma.V0}");
                ulong seed = (ulong)DateTime.Now.Ticks;
                Console.WriteLine($"seed = {seed}");
                //根据均值和标准差,随机生成25个正态分布坐标点作为样本
                CvInvoke.Randn(rows, mean, sigma);
            }
            CvInvoke.cvReshape(samples.Ptr, samples.Ptr, 1, 0);

            //using (EM emModel1 = new EM())
            using (EM emModel1 = new EM())
            {
                emModel1.ClustersNumber = 4;
                emModel1.CovarianceMatrixType = EM.CovarianMatrixType.Spherical;
                emModel1.TermCriteria = new MCvTermCriteria(300, 0.000001);
                //emModel1.Train(samples,Emgu.CV.ML.MlEnum.DataLayoutType.RowSample, labels);
                emModel1.trainE(samples, means0, null,null,null,labels,probs0);
                emModel1.TrainM(samples, probs0, null, labels, probs0);
                #region Classify every image pixel
                for (int i = 0; i < img.Height; i++)
                    for (int j = 0; j < img.Width; j++)
                    {
                        sample.Data[0, 0] = i;
                        sample.Data[0, 1] = j;
                        MCvPoint2D64f mCvPoint2D64F = emModel1.Predict(sample, null);
                        //这里做测试,看预测结果的分类
                        //Console.WriteLine($"{j},{i}|{mCvPoint2D64F.X},{mCvPoint2D64F.Y}");
                        int response = (int)(mCvPoint2D64F.X);
                        //Console.WriteLine($"response = {response}");
                        Bgr color = colors[response];

                        img.Draw(
                           new CircleF(new PointF(i, j), 1),
                           new Bgr(color.Blue * 0.5, color.Green * 0.5, color.Red * 0.5),
                           //color,
                           0);
                    }
                #endregion

                #region draw the clustered samples
                for (int i = 0; i < nSamples; i++)
                {
                    img.Draw(new CircleF(new PointF(samples.Data[i, 0], samples.Data[i, 1]), 1), colors[labels.Data[i, 0]], 0);
                }
                #endregion
                Emgu.CV.UI.ImageViewer.Show(img,"EM Image Result");
            }
        }

调用:

		static void Main(string[] args)
        {
            EmBase();
        }

结果展示

预测结果显示

提出问题

根据What is an Expectaion-Maximization Classifier的解释,EM迭代方法交替执行期望(E)步骤和一个最大化(M)的步骤,即EM类中的TrianE和TrianM方法,EM类继承自EM : UnmanagedObject, IStatModel, IAlgorithm,其重写了IStatModel中的Train方法,该方法是TrianE和TrianM的合并,所以理论上直接执行emModel1.Train即可,但是本文测试时,直接在使用Trian方法并未获取到样本的标签分类结果,导致后面的样本点分布不正确,所以才分布进行训练,希望大家指正!

根据提供的引用内容,以下是一个新手学习C#编程语言机器视觉方向的学习路线指南: 1. 首先,你需要学习C#编程语言的基础知识。这包括掌握语言的语法、数据类型、流程控制等基本概念,并且熟悉C#的开发环境和工具,比如Visual Studio(简称VS)。 2. 接下来,你需要学习机器视觉的基本原理和概念。这包括了解图像处理、特征提取、目标检测和识别等基本技术。了解机器视觉的基本概念可以帮助你理解在C#中如何应用这些技术。 3. 一旦你掌握了C#和机器视觉的基本知识,你可以开始学习相关的库和框架。在C#中,你可以使用OpenCVSharp、Emgu CV等库来进行图像处理和机器视觉任务。这些库提供了丰富的函数和算法,可以帮助你处理图像、进行特征提取和目标检测等任务。熟悉这些库的使用可以提高你的机器视觉编程能力。 4. 此外,你还可以学习深度学习和神经网络的知识。深度学习在机器视觉任务中发挥着重要作用,可以帮助你实现更高级的图像处理和识别任务。学习深度学习的框架,比如TensorFlow.NET、CaffeSharp等,可以帮助你在C#中应用深度学习算法。 5. 最后,不断练习和实践是提高机器视觉编程能力的关键。通过完成项目和参与实际的机器视觉应用,你可以不断提升自己的技能和经验。参加相关的机器视觉竞赛和社区活动,与其他开发者交流和分享经验也是很有帮助的。 综上所述,新手学习C#编程语言机器视觉方向的学习路线包括学习C#基础知识、了解机器视觉的基本概念、学习相关的库和框架、掌握深度学习和神经网络的知识,并通过实践不断提升自己的技能和经验。希望这个学习路线指南对你有所帮助。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [机器视觉工程师如何高效学习C#](https://blog.youkuaiyun.com/weixin_44301520/article/details/129515409)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [新手学习C#常见技能_视觉检测](https://blog.youkuaiyun.com/hspx668/article/details/129518483)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值