当前位置: 首页 > news >正文

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

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

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

Cv2.CvtColorTwoPlane

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

摘要:Cv2.CvtColorTwoPlane专门处理 YUV420 双平面到 RGB/BGR 的转换。它最容易讲清楚“第一个平面是亮度 Y,第二个平面是交错的 UV 或 VU”这一点,也非常适合用来入门 NV12 和 NV21。

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

publicstaticvoidCvtColorTwoPlane(InputArraysrc1,InputArraysrc2,OutputArraydst,ColorConversionCodescode)

2. 函数用途

Cv2.CvtColorTwoPlane用来把双平面 YUV420 图像转换成 RGB/BGR 图像。

它最常见的用途有:

  1. 处理来自视频流、硬件解码器或摄像头的 NV12 / NV21 数据。
  2. 把 Y 平面和 UV 平面合并还原成可显示的彩色图像。
  3. 在不额外手工拼接大矩阵的情况下,直接完成双平面颜色转换。
  4. 作为讲解 YUV420 采样格式的教学入口。

3. 函数公式

这个函数的核心不是一个固定公式,而是一个“双平面输入 + 指定转换码”的映射关系:

d s t = T c o d e ( Y , U V ) dst = T_{code}(Y, UV)dst=Tcode(Y,UV)

其中:

  1. Y表示亮度平面。
  2. UV表示交错的色度平面。
  3. code决定你要按 NV12 还是 NV21 来解释第二个平面。

从尺寸上看,典型的 YUV420 双平面可以理解为:

Y ∈ C V 8 U C 1 H × W , U V ∈ C V 8 U C 2 H 2 × W 2 Y \in CV_{8UC1}^{H\times W}, \qquad UV \in CV_{8UC2}^{\frac{H}{2}\times\frac{W}{2}}YCV8UC1H×W,UVCV8UC22H×2W

也就是说:

  1. src1是完整的 Y 平面。
  2. src2是按 2x2 下采样后的色度平面。
  3. 输出图像的尺寸和 Y 平面相同。

4. 函数原理说明

YUV420 的含义可以拆成两部分理解:

  1. Y负责亮度,所以它通常是单通道,并且和最终图像大小相同。
  2. UV负责色彩,但它的分辨率更低,因为人眼对色度的敏感度低于亮度。

NV12 和 NV21 的差别只在于第二个平面的顺序:

  1. NV12:U, V, U, V, ...
  2. NV21:V, U, V, U, ...

对初学者来说,最容易犯的错就是把 NV12 和 NV21 混用。它们的输入数据看起来非常像,但色彩解释顺序不同,最终输出会明显偏色。

5. 参数含义解析

参数名类型必填含义
src1InputArrayY 平面,8 位单通道图像
src2InputArray交错的 UV 或 VU 平面
dstOutputArray输出图像
codeColorConversionCodes只支持 NV12 / NV21 系列转换码

补充说明:

  1. src1是亮度平面。
  2. src2是交错的色度平面。
  3. dst通常是 3 通道 BGR/RGB 或 4 通道 BGRA/RGBA。
  4. 绑定层目前只支持 YUV420 到 RGB/BGR 的双平面转换。

6. 应用场景列表

场景名场景说明典型用途
场景A:NV12 解码Y + UV组合还原成 BGR 图视频帧显示、解码后预览
场景B:NV21 解码Y + VU组合还原成 BGR 图安卓相机数据处理
场景C:Y 平面分析单独观察亮度层亮度检测、曝光分析
场景D:UV 平面分析单独观察色度层色偏排查、格式调试

7. 函数使用示例(与 WPF 场景一一对应)

说明:下面代码对应 WPF 页面里的CvtColorTwoPlane场景。为了让初学者更容易理解,这里直接手工构造 Y 平面和 UV 平面,再分别按 NV12 和 NV21 解释它们。

usingSystem;usingOpenCvSharp;internalstaticclassProgram{privatestaticvoidMain(){// 先构造一个很小的 Y 平面,便于理解双平面数据的结构。usingvaryPlane=newMat(8,8,MatType.CV_8UC1);for(varrow=0;row<yPlane.Rows;row++){for(varcol=0;col<yPlane.Cols;col++){// 亮度从左到右缓慢变化,这样输出图像能看出明暗梯度。vary=50+col*20;yPlane.At<byte>(row,col)=(byte)Math.Clamp(y,0,255);}}// UV 平面是 4x4,每个元素是一个 U/V 对,对应 2x2 的 Y 像素块。usingvaruvPlane=newMat(4,4,MatType.CV_8UC2);FillUvBlock(uvPlane,0,0,2,2,84,240);FillUvBlock(uvPlane,0,2,2,2,54,60);FillUvBlock(uvPlane,2,0,2,2,220,108);FillUvBlock(uvPlane,2,2,2,2,128,128);// 同一张双平面数据,按照 NV12 和 NV21 两种方式解释,会得到不同的颜色结果。usingvarnv12=newMat();usingvarnv21=newMat();Cv2.CvtColorTwoPlane(yPlane,uvPlane,nv12,ColorConversionCodes.YUV2BGR_NV12);Cv2.CvtColorTwoPlane(yPlane,uvPlane,nv21,ColorConversionCodes.YUV2BGR_NV21);// 把结果保存出来,初学者可以直接对比 NV12 和 NV21 的色彩差异。Cv2.ImWrite("cvtcolortwoplane_y.png",yPlane);Cv2.ImWrite("cvtcolortwoplane_uv.png",CreateUvPreview(uvPlane));Cv2.ImWrite("cvtcolortwoplane_nv12.png",nv12);Cv2.ImWrite("cvtcolortwoplane_nv21.png",nv21);Console.WriteLine("CvtColorTwoPlane 演示已完成。");}privatestaticvoidFillUvBlock(MatuvPlane,intstartRow,intstartCol,introws,intcols,byteu,bytev){// 把一块区域的 UV 值填成相同的颜色,方便观察不同色度组合的效果。for(varrow=startRow;row<startRow+rows;row++){for(varcol=startCol;col<startCol+cols;col++){uvPlane.Set(row,col,newVec2b(u,v));}}}privatestaticMatCreateUvPreview(MatuvPlane){// UV 是双通道矩阵,不适合直接按 BGR 显示,所以这里拆开后做热力图。varchannels=Cv2.Split(uvPlane);try{usingvaruHeat=CreateHeatmap(channels[0]);usingvarvHeat=CreateHeatmap(channels[1]);returnCv2.HConcat(uHeat,vHeat);}finally{foreach(varchannelinchannels){channel.Dispose();}}}privatestaticMatCreateHeatmap(Matsource){usingvarnormalized=newMat();source.ConvertTo(normalized,MatType.CV_8UC1);varpreview=newMat();Cv2.ApplyColorMap(normalized,preview,ColormapTypes.Turbo);returnpreview;}}

8. 常见错误与避坑

  1. 把 NV12 和 NV21 的第二平面顺序搞反。
  2. src2当成普通 3 通道彩色图,而不是交错的 UV 平面。
  3. src1src2的尺寸不符合 YUV420 结构。
  4. 传入了不在支持列表里的转换码。
  5. 误以为这个函数可以处理任意 YUV 格式,其实它只处理当前绑定层支持的 YUV420 双平面格式。

9. 进阶扩展

  1. 可以把视频解码器输出的 NV12 帧直接接进这个函数,减少中间拷贝。
  2. 可以先观察 Y 平面,再单独分析 UV 平面的色偏。
  3. 可以把 NV12 和 NV21 的解码结果并排显示,用来排查摄像头格式错误。
  4. 可以把这个函数和CvtColor结合起来,做从 YUV 到 Lab/HSV 的进一步分析。

10. 小结

Cv2.CvtColorTwoPlane的关键不是“转色”本身,而是“正确理解双平面布局”。只要记住下面三点,就不容易写错:

  1. src1是 Y 平面。
  2. src2是交错的 UV 或 VU 平面。
  3. code决定你到底按 NV12 还是 NV21 来解释数据。

11. 相关链接

  • WPF 教学控件:Cv2CvtColorTwoPlaneControl.xaml.cs
  • 样例实现:CvtColorTwoPlaneSample.cs
  • 官方文档源码位置:OpenCvSharp/Cv2/Cv2_imgproc.cs:2483
http://www.gsyq.cn/news/1429833.html

相关文章:

  • 双系统Ubuntu18.04升级22.04,安装docker进行openclaw安装
  • 【电赛保姆级教程】别在比赛时从零写代码了!电赛“祖传代码库”搭建与OLED多级菜单硬核指南
  • 2026年5月AI模型性能排行:代码能力Claude霸榜,智谱GLM杀入前十
  • 调试记录 - 2024年1月15日
  • 告别排版焦虑:西安交大LaTeX论文模板让你专注学术创新
  • 【电赛保姆级教程】别再用L298N了!电赛电机驱动与高阶控制(带FOC扫盲)硬核避坑指南
  • LabVIEW与外部设备通信秘籍:用DLL传递复杂结构体(含数组/嵌套结构)的完整配置流程
  • 那些年,我追Google Trends追到精疲力尽的故事
  • 深入FIO引擎:除了libaio,这些ioengine(如sync, psync, mmap)在Linux下到底怎么选?性能差多少?
  • 口袋神器!Arduino 创客必备,可接入 DeepSeek、Qwen 等 AI 大模型,通过 GPIO 串口控制 IoT 智能设备
  • C# 泛型
  • C++之父开撕AI Coding:资深开发者宁愿退休也不愿伺候AI生成的代码
  • 为什么你的论文参考文献格式总是不对?3个GB/T 7714 BibTeX样式终极解决方案
  • 187、运动控制中的行业应用:机械臂力控打磨
  • 前端内存泄漏常见场景与排查
  • GTA5线上小助手:免费开源工具帮你轻松称霸洛圣都终极指南
  • Kettle官网大变样?别慌!手把手教你找到最新9.3版本的下载入口(附Hadoop Shims获取指南)
  • 【AI+房地产实战指南】:2024年最值得落地的7大智能整合场景与避坑清单
  • ARP 协议:网络世界里的“地址翻译官“
  • SBM-20-1盖革管3D打印端盖制作:从零打造专业级辐射探测器接口
  • 2026AI漫剧创作深度测评:如何为你的创作需求匹配最佳方案? - 速递信息
  • 189、运动控制中的行业应用:医疗设备(手术机器人)
  • 英雄联盟R3nzSkin换肤工具实战指南:国服安全自定义皮肤完整方案
  • yuzu模拟器架构深度解析:从Switch硬件仿真到跨平台渲染优化
  • 2026年AI漫剧创作推荐榜:主流工具平台深度测评,优质品牌选型指南 - 速递信息
  • Translumo:专为游戏玩家设计的屏幕实时翻译工具,打破语言障碍的终极解决方案
  • 平台算法审核已升级!你的AI视频正被自动标记为“潜在侵权内容”(附2024主流平台检测逻辑逆向分析)
  • TPAMI 2026 | DC-SAM 横空出世!融合 SAM 特征,打造图像视频通用上下文分割框架
  • 2026年专业做床垫的公司哪家强?南宁市雅兰床垫值得一探! - 资讯快报
  • 2026年华为OD机试(A卷,100分)- 机器人(Java JS Python)带详细答案和源码