news 2026/5/27 8:19:05

OpencvSharp 算子学习教案之 - Cv2.CalcCovarMatrix 重载1

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpencvSharp 算子学习教案之 - Cv2.CalcCovarMatrix 重载1

OpencvSharp 算子学习教案之 - Cv2.CalcCovarMatrix 重载1

大家好,Opencv在很多工程项目中都会用到,而OpencvSharp则是以C#开发与实现的Opencv操作库,对.NET开发人员友好,但很多API的中文资料、应用场景及常见坑点等缺乏系统性归纳,因此这系列博客将给大家带来Cv2及Mat对象全系列算子学习教案,供大家参考学习。

Cv2.CalcCovarMatrix

  • 教案版本:V1.0
  • 面向对象:OpenCvSharp 初学者
  • 所属模块:core
  • 源码位置:OpenCvSharp/Cv2/Cv2_core.cs:2545

摘要:InputArray 重载适合“样本已经排成一个矩阵”的情况。本文用一个三行两列的样本矩阵演示 Rows 标志的含义,并帮助初学者理解协方差矩阵与均值向量是怎样从单个输入矩阵里计算出来的。

1. 函数名称(带参数签名)

publicstaticvoidCalcCovarMatrix(InputArraysamples,OutputArraycovar,InputOutputArraymean,CovarFlagsflags,MatType?ctype=null)

2. 函数用途

Cv2.CalcCovarMatrix的这个重载,会从一个已经排好行或列的矩阵中计算协方差矩阵和均值向量。

它最常见的用途有:

  1. 处理表格型样本数据。
  2. 对已经堆叠好的特征矩阵做统计分析。
  3. 为 PCA、马氏距离等算法准备协方差基础数据。

如果你的数据已经是一个大矩阵,这个重载通常比先拆成Mat[]更直接。

3. 函数公式

协方差矩阵的常见定义是:

cov⁡(x)=1N∑i=1N(xi−μ)(xi−μ)T \operatorname{cov}(x) = \frac{1}{N} \sum_{i=1}^{N} (x_i - \mu)(x_i - \mu)^Tcov(x)=N1i=1N(xiμ)(xiμ)T

其中:

  • NNN是样本个数;
  • xix_ixi是第iii条样本;
  • μ\muμ是均值向量。

本文示例把样本放在矩阵的每一行:

[123456] \begin{bmatrix} 1 & 2 \\ 3 & 4 \\ 5 & 6 \end{bmatrix}135246

它的均值向量是:

[3,4] [3, 4][3,4]

归一化后的协方差矩阵仍然是:

[83838383] \begin{bmatrix} \frac{8}{3} & \frac{8}{3} \\ \frac{8}{3} & \frac{8}{3} \end{bmatrix}[38383838]

4. 函数原理说明

CalcCovarMatrix(InputArray samples, ...)可以理解成:

  1. 读取输入矩阵。
  2. 根据RowsCols判断哪一个方向是样本方向。
  3. 先计算均值向量。
  4. 再把每条样本减去均值。
  5. 最后组合成协方差矩阵。

对初学者来说,最容易混淆的是RowsCols的方向选择。这个重载本身非常灵活,但也因此更容易写错标志位。

5. 参数含义解析

参数名类型必填含义
samplesInputArray输入样本矩阵
covarOutputArray输出协方差矩阵
meanInputOutputArray输入/输出均值向量
flagsCovarFlags协方差计算方式相关标志
ctypeMatType?输出矩阵类型,默认可由 OpenCV 选择

补充说明:

  1. 如果样本放在行里,就用Rows
  2. 如果样本放在列里,就用Cols
  3. Normal负责使用常规协方差公式。
  4. Scale负责按样本个数归一化。
  5. mean既可以作为输出,也可以在UseAvg时作为输入均值。

6. 应用场景列表

场景名场景说明典型用途
场景A:表格型数据每一行就是一条样本数据分析入门
场景B:行样本统计直接按行算协方差特征工程
场景C:PCA 前置处理先求协方差再分解降维教学

7. 函数使用示例

下面的 Console 程序演示Cv2.CalcCovarMatrix(InputArray samples, ...)。为了让结果更容易看懂,我们把三条样本直接排成一个矩阵,并且明确告诉函数“每一行都是一条样本”。

usingSystem.Text;usingOpenCvSharp;internalstaticclassProgram{/// <summary>/// 程序入口。/// </summary>privatestaticvoidMain(){// 控制台要支持中文输出,避免说明文字乱码。Console.OutputEncoding=Encoding.UTF8;// 这里把三条样本直接放进一个矩阵里,每一行都代表一条观测值。varsourceData=newdouble[,]{{1.0,2.0},{3.0,4.0},{5.0,6.0},};usingvarsource=CreateMatrix(sourceData);usingvarcovariance=newMat();usingvarmean=newMat();// Rows 表示“每一行都是一条样本”,Normal 和 Scale 仍然分别负责公式和归一化。Cv2.CalcCovarMatrix(source,covariance,mean,CovarFlags.Rows|CovarFlags.Normal|CovarFlags.Scale,MatType.CV_64FC1);varactualCovariance=ReadDoubleMatrix(covariance);varactualMean=ReadDoubleMatrix(mean);varexpectedCovariance=newdouble[,]{{8.0/3.0,8.0/3.0},{8.0/3.0,8.0/3.0},};varexpectedMean=newdouble[,]{{3.0,4.0},};Console.WriteLine("InputArray 重载的输出结果");PrintMatrix("样本矩阵(每一行都是一条样本)",sourceData);PrintMatrix("协方差矩阵",actualCovariance);PrintMatrix("均值向量",actualMean);PrintMatrix("期望协方差矩阵",expectedCovariance);PrintMatrix("期望均值向量",expectedMean);}/// <summary>/// 把二维数组写入 Mat。/// </summary>privatestaticMatCreateMatrix(double[,]values){returnMat.FromPixelData(values.GetLength(0),values.GetLength(1),MatType.CV_64FC1,values);}/// <summary>/// 从 Mat 读取 double 二维数组。/// </summary>privatestaticdouble[,]ReadDoubleMatrix(Matsource){usingvarconverted=newMat();source.ConvertTo(converted,MatType.CV_64FC1);varresult=newdouble[converted.Rows,converted.Cols];for(varrow=0;row<converted.Rows;row++){for(varcol=0;col<converted.Cols;col++){result[row,col]=converted.At<double>(row,col);}}returnresult;}/// <summary>/// 打印矩阵内容。/// </summary>privatestaticvoidPrintMatrix(stringtitle,double[,]matrix){Console.WriteLine(title);for(varrow=0;row<matrix.GetLength(0);row++){varline=newStringBuilder("[");for(varcol=0;col<matrix.GetLength(1);col++){line.Append(matrix[row,col].ToString("F6",System.Globalization.CultureInfo.InvariantCulture));if(col<matrix.GetLength(1)-1){line.Append(", ");}}line.Append(']');Console.WriteLine(line.ToString());}Console.WriteLine();}}

8. 运行结果解读

运行后,你会看到:

  1. 输出的均值向量和 Mat[] 版本一致。
  2. 协方差矩阵的数值也和手工结果一致。
  3. 只要 Rows 标志写对,单矩阵输入就非常直接。

这说明 InputArray 重载特别适合已经整理好的表格型样本数据。

9. 常见误区与注意事项

  1. 不要忘记写RowsCols
  2. 不要把样本方向写反。
  3. 不要把NormalScale的作用混淆。
  4. 如果你已经有均值,也可以考虑配合UseAvg减少重复计算。

10. 扩展思考

如果你的数据是按列保存的,只要把Rows改成Cols,同一套思路也能继续使用。

这个函数和Eigen经常配套出现,因为协方差矩阵本身往往就是后续特征分解的输入。

11. 小结

InputArray 重载最适合“样本已经排成一个矩阵”的情况。

只要你能分清样本是按行还是按列存放,这个函数就很好理解。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/27 8:13:08

基于MCP协议构建智能求职助手:从架构设计到工程实践

1. 项目概述&#xff1a;一个为求职者量身定制的免费智能助手最近&#xff0c;我的一位技术极客好友&#xff08;也是我最好的朋友&#xff09;完成了一个让我眼前一亮的项目&#xff1a;他搭建了一个完全免费的MCP服务器&#xff0c;专门用来辅助求职。如果你正在找工作&#…

作者头像 李华
网站建设 2026/5/27 8:13:04

STM32-TIM输出比较(十二)

TIM输出比较STM32定时器的输出比较功能啊&#xff0c;这个输出比较功能还是非常重要的。它主要是用来输出 PWM 波形的&#xff0c; PWM 波形又是驱动电机的必要条件。所以你如果想用 STM32 做一些有电机的项目&#xff0c;比如智能车、机器人等啊&#xff0c;那这个输出比较功能…

作者头像 李华
网站建设 2026/5/27 8:12:15

UniversalUnityDemosaics:终极Unity游戏视觉恢复工具完整指南

UniversalUnityDemosaics&#xff1a;终极Unity游戏视觉恢复工具完整指南 【免费下载链接】UniversalUnityDemosaics A collection of universal demosaic BepInEx plugins for games made in Unity3D engine 项目地址: https://gitcode.com/gh_mirrors/un/UniversalUnityDem…

作者头像 李华
网站建设 2026/5/27 8:08:19

如何快速解锁原神60帧限制:终极帧率优化指南

如何快速解锁原神60帧限制&#xff1a;终极帧率优化指南 【免费下载链接】genshin-fps-unlock unlocks the 60 fps cap 项目地址: https://gitcode.com/gh_mirrors/ge/genshin-fps-unlock genshin-fps-unlock是一款专为《原神》玩家设计的开源帧率解锁工具&#xff0c;采…

作者头像 李华
网站建设 2026/5/27 8:00:58

UniApp 快速集成个推推送(UniPush2.0)完整实战教程

uni-app 接入个推&#xff0c;官方推荐用 uni-push 2.0&#xff08;底层由个推提供&#xff09;&#xff0c;不用自己集成原生 SDK&#xff0c;全程在 HBuilderX DCloud 开发者中心配置即可。下面按“开通→配置→客户端→测试→常见坑”一步步来。 一、基本概念 个推&#x…

作者头像 李华