资讯动态

OpencvSharp 算子学习教案之 - Cv2.Accumulate

发布时间:2026/8/8 18:06:29 来源:尧图企业网站定制
OpencvSharp 算子学习教案之 - Cv2.Accumulate大家好Opencv在很多工程项目中都会用到而OpencvSharp则是以C#开发与实现的Opencv操作库对.NET开发人员友好但很多API的中文资料、应用场景及常见坑点等缺乏系统性归纳因此这系列博客将给大家带来Cv2及Mat对象全系列算子学习教案供大家参考学习。Cv2.Accumulate教案版本V1.0面向对象OpenCvSharp 初学者所属模块imgproc源码位置OpenCvSharp/Cv2/Cv2_imgproc.cs:1542摘要Cv2.Accumulate 会把源图像逐像素加到累加器里常用于背景统计、多帧求和和连续帧分析。本文先解释 mask 和浮点累加器的作用再用一个 5x5 小矩阵演示多帧累加的具体过程。1. 函数名称带参数签名publicstaticvoidAccumulate(InputArraysrc,InputOutputArraydst,InputArraymask)2. 函数用途Cv2.Accumulate的作用是把输入图像的像素值加到已有累加器上。它最常见的用途有累积背景统计量。把多帧图像加成一张总和图。作为后续平均、方差或前景分析的基础步骤。这类操作最重要的一点是dst不能用 8 位图像保存因为累加多次后数值会越来越大因此通常要使用 32F 或 64F。3. 函数公式设源图像为s r c srcsrc累加器为d s t dstdst掩码为m a s k maskmask则更新规则为d s t ( x , y ) ← d s t ( x , y ) s r c ( x , y ) if m a s k ( x , y ) ≠ 0 dst(x,y) \leftarrow dst(x,y) src(x,y) \quad \text{if } mask(x,y) \neq 0dst(x,y)←dst(x,y)src(x,y)ifmask(x,y)0如果mask(x,y)0那么该位置不会参与累加。4. 函数原理说明先准备一个浮点累加器dst。每来一帧就把该帧的像素加进去。如果提供了 mask就只在 mask 非零的区域更新。累加完成后可以继续做平均、统计或背景建模。初学者最容易混淆的是以为dst可以直接是 8 位图像。以为mask是可有可无的装饰参数。不清楚Accumulate是逐像素加法而不是平均值。忘记多次累加后数值会迅速变大。5. 参数含义解析参数名类型必填含义典型输入/输出形状srcInputArray是输入图像1 或 3 通道图像dstInputOutputArray是累加器与 src 同尺寸、浮点类型maskInputArray是掩码单通道 8 位图像补充说明src支持 8 位或浮点图像。dst通常要用 32F 或 64F。mask为 0 的位置不会更新。6. 应用场景列表场景名场景说明输入输出场景A背景统计连续多帧逐像素累加视频帧累加器场景B多帧求和把多张图像直接叠加多张输入图总和图场景C局部统计只在 mask 指定区域更新输入图 掩码局部累加器7. 函数使用示例下面的 Console 程序会构造两帧小型灰度矩阵并把它们累加到同一个 32F 累加器里。为了方便观察只让中心 3x3 区域参与累加。usingSystem;usingSystem.Text;usingOpenCvSharp;internalstaticclassProgram{/// summary/// 程序入口。/// /summaryprivatestaticvoidMain(){// 让控制台支持中文输出便于阅读教学说明。Console.OutputEncodingEncoding.UTF8;// 构造两帧 5x5 灰度图第二帧在第一帧基础上整体增加 10方便观察累加结果。usingvarsrc1CreateDemoImage(0);usingvarsrc2CreateDemoImage(10);// 准备一个中心掩码只让中间 3x3 区域参与累加。usingvarmaskCreateCenterMask(newSize(5,5));// 累加器必须使用浮点类型因为它需要保存多帧相加后的结果。usingvardstnewMat(5,5,MatType.CV_32FC1,Scalar.All(0));// 依次把两帧图像加到累加器里。Cv2.Accumulate(src1,dst,mask);Cv2.Accumulate(src2,dst,mask);// 打印每一步的矩阵方便初学者手算核对。Console.WriteLine(src1 );PrintMatrix(src1);Console.WriteLine(src2 );PrintMatrix(src2);Console.WriteLine(mask );PrintMatrix(mask);Console.WriteLine(dst );PrintMatrix(dst);}/// summary/// 创建 5x5 的教学矩阵数值从 1 开始递增。/// /summary/// param nameoffset所有像素统一增加的偏移量。/param/// returns单通道灰度图。/returnsprivatestaticMatCreateDemoImage(intoffset){// 使用单通道 8 位矩阵便于看到每个像素值的变化。varimagenewMat(5,5,MatType.CV_8UC1);for(varrow0;rowimage.Rows;row){for(varcol0;colimage.Cols;col){// 这里用简单的递增序列让读者可以快速手算每个位置的值。image.Set(row,col,(byte)(row*image.Colscol1offset));}}returnimage;}/// summary/// 创建一个中心 3x3 的掩码。/// /summary/// param namesize掩码尺寸。/param/// returns单通道 8 位掩码。/returnsprivatestaticMatCreateCenterMask(Sizesize){// 先创建全 0 掩码再把中心区域填成 255。varmasknewMat(size.Height,size.Width,MatType.CV_8UC1,Scalar.All(0));Cv2.Rectangle(mask,newRect(1,1,3,3),Scalar.All(255),-1);returnmask;}/// summary/// 打印单通道矩阵。/// /summary/// param namematrix待打印矩阵。/paramprivatestaticvoidPrintMatrix(Matmatrix){// 先统一转成 64F方便按 double 读取和输出。usingvarmatrix64newMat();matrix.ConvertTo(matrix64,MatType.CV_64FC1);for(varrow0;rowmatrix64.Rows;row){Console.Write([);for(varcol0;colmatrix64.Cols;col){Console.Write(matrix64.Atdouble(row,col).ToString(F0));if(colmatrix64.Cols-1){Console.Write(, );}}Console.WriteLine(]);}Console.WriteLine();}}8. 注意事项dst必须是浮点类型。mask为 0 的位置不会被累加。连续多帧累加时数值会越来越大。如果你想直接求平均可以在累加后再除以帧数。9. 调优建议初学者先用小矩阵理解累加规则再迁移到真实视频。如果你只关心局部区域可以先设计好 mask。当你要做背景建模时Accumulate常常是第一步。10. 运行说明如果你在控制台工程里运行本文示例直接把代码放进Program.cs即可。如果你在本仓库里学习请打开 WPF 控件 Cv2AccumulateControl.xaml.cs 对应的页面。点击“运行场景A”可以在右侧查看多帧累加后的结果。11. 常见错误排查把dst误设成 8 位图像导致累加结果溢出或截断。忘记mask为 0 的区域不会更新。误把累加当成平均值。不了解多帧累加后需要再做归一化或除以帧数。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价