OpencvSharp 算子学习教案之 - Cv2.CvtColor
OpencvSharp 算子学习教案之 - Cv2.CvtColor
大家好,Opencv在很多工程项目中都会用到,而OpencvSharp则是以C#开发与实现的Opencv操作库,对.NET开发人员友好,但很多API的中文资料、应用场景及常见坑点等缺乏系统性归纳,因此这系列博客将给大家带来Cv2及Mat对象全系列算子学习教案,供大家参考学习。
Cv2.CvtColor
- 教案版本:V1.0
- 面向对象:OpenCvSharp 初学者
- 所属模块:imgproc
- 源码位置:OpenCvSharp/Cv2/Cv2_imgproc.cs:2450
摘要:Cv2.CvtColor是最常用的颜色空间转换函数。它可以在 BGR、GRAY、HSV、BGRA 等多种格式之间转换,也可以通过dstCn影响输出通道数,是理解图像通道变化的必学入口。
1. 函数名称(带参数签名)
publicstaticvoidCvtColor(InputArraysrc,OutputArraydst,ColorConversionCodescode,intdstCn=0)2. 函数用途
Cv2.CvtColor用来把图像从一种颜色空间转换到另一种颜色空间。
它最常见的用途有:
- 把彩色图转成灰度图,便于二值化、边缘检测和阈值处理。
- 把 BGR 转成 HSV、YCrCb、Lab 等颜色空间,方便做颜色分析。
- 给图像补上 alpha 通道,生成 BGRA 或 RGBA 图像。
- 把单通道图再扩展成三通道图,方便后续算法继续使用。
3. 函数公式
这个函数没有单一的数学公式,因为不同code对应的是不同的颜色变换规则。更适合这样理解:
d s t = T c o d e ( s r c , d s t C n ) dst = T_{code}(src, dstCn)dst=Tcode(src,dstCn)
其中:
T_{code}表示某一个具体的颜色转换规则。src是输入图像。dstCn用来控制输出通道数,默认值0表示自动推导。
对常见的几种转换,可以这样记:
BGR2GRAY:3 通道压成 1 通道。BGR2HSV:3 通道变成另一套 3 通道表示。BGR2BGRA:3 通道扩展成 4 通道。GRAY2BGR:1 通道扩展成 3 通道。
4. 函数原理说明
CvtColor的工作方式可以分成三层理解:
- 先根据
code判断输入输出的颜色空间关系。 - 再根据输入图像的通道数和深度,做对应的数值变换。
- 最后按照目标格式写出结果。
对初学者来说,最重要的是记住下面这些规则:
src和dst的尺寸通常相同。- 输出深度通常和输入一致。
- 输出通道数取决于
code,也可能受dstCn影响。 - 如果你只是想“看见颜色变化”,最常见的就是 BGR、GRAY、HSV 这几种组合。
5. 参数含义解析
| 参数名 | 类型 | 必填 | 含义 |
|---|---|---|---|
| src | InputArray | 是 | 输入图像 |
| dst | OutputArray | 是 | 输出图像 |
| code | ColorConversionCodes | 是 | 颜色转换代码 |
| dstCn | int | 否 | 目标通道数,0表示自动推导 |
补充说明:
src可以是 8 位、16 位或单精度浮点图像。dst的尺寸通常与src相同。dstCn = 0时,OpenCV 会根据code自动决定输出通道数。- 某些转换会改变通道数,例如
BGR2GRAY和GRAY2BGR。
6. 应用场景列表
| 场景名 | 场景说明 | 典型用途 |
|---|---|---|
| 场景A:BGR 转灰度 | 把彩色图压缩成单通道图 | 阈值、边缘、轮廓 |
| 场景B:BGR 转 HSV | 把颜色信息拆成色相、饱和度、明度 | 颜色分割、颜色筛选 |
| 场景C:BGR 加 alpha | 给图像补上透明度通道 | UI 合成、透明图输出 |
| 场景D:GRAY 转 BGR | 把单通道图扩展成三通道 | 兼容后续彩色算法 |
7. 函数使用示例(与 WPF 场景一一对应)
说明:下面示例对应 WPF 页面里的
CvtColor场景。为了让初学者更容易观察,我们把 HSV 再拆成三个通道热力图单独查看。
usingSystem;usingOpenCvSharp;internalstaticclassProgram{privatestaticvoidMain(){// 构造一张彩色教学图,方便观察不同颜色空间的差异。usingvarsource=CreateColorDemoCard();// 常见的几种颜色转换:灰度、HSV、BGRA,以及灰度再转回 BGR。usingvargray=newMat();usingvarhsv=newMat();usingvarbgra=newMat();usingvargrayToBgr=newMat();Cv2.CvtColor(source,gray,ColorConversionCodes.BGR2GRAY);Cv2.CvtColor(source,hsv,ColorConversionCodes.BGR2HSV);Cv2.CvtColor(source,bgra,ColorConversionCodes.BGR2BGRA);Cv2.CvtColor(gray,grayToBgr,ColorConversionCodes.GRAY2BGR);// 把 HSV 的三个通道拆开,分别保存成热力图,便于初学者观察每个通道的数值变化。varhsvChannels=Cv2.Split(hsv);try{SaveHeatmap(hsvChannels[0],"cvtcolor_h.png");SaveHeatmap(hsvChannels[1],"cvtcolor_s.png");SaveHeatmap(hsvChannels[2],"cvtcolor_v.png");}finally{foreach(varchannelinhsvChannels){channel.Dispose();}}// 保存所有结果,方便对照查看。Cv2.ImWrite("cvtcolor_source.png",source);Cv2.ImWrite("cvtcolor_gray.png",gray);Cv2.ImWrite("cvtcolor_hsv_raw.png",hsv);Cv2.ImWrite("cvtcolor_bgra.png",bgra);Cv2.ImWrite("cvtcolor_gray_to_bgr.png",grayToBgr);Console.WriteLine("CvtColor 演示已完成。");}privatestaticMatCreateColorDemoCard(){// 这张图故意放几种不同颜色的几何图形,便于观察颜色空间转换后的差异。varcanvas=newMat(240,360,MatType.CV_8UC3,newScalar(244,241,236));Cv2.Rectangle(canvas,newRect(20,26,108,78),newScalar(58,148,240),-1,LineTypes.AntiAlias);Cv2.Circle(canvas,newPoint(204,86),48,newScalar(76,220,126),-1,LineTypes.AntiAlias);Cv2.Ellipse(canvas,newPoint(274,172),newSize(66,42),-15,0,360,newScalar(220,108,78),-1,LineTypes.AntiAlias);Cv2.PutText(canvas,"BGR",newPoint(144,220),HersheyFonts.HersheySimplex,0.95,newScalar(40,40,40),2,LineTypes.AntiAlias);returncanvas;}privatestaticvoidSaveHeatmap(MatsingleChannel,stringfileName){// 先把单通道数据映射到 0~255,再套一层热力图,方便肉眼观察数值分布。usingvarnormalized=newMat();singleChannel.ConvertTo(normalized,MatType.CV_8UC1);usingvarheatmap=newMat();Cv2.ApplyColorMap(normalized,heatmap,ColormapTypes.Turbo);Cv2.ImWrite(fileName,heatmap);}}8. 常见错误与避坑
- 选错
code,例如把 BGR 图误当成 RGB 图处理。 - 忘记
dstCn = 0的默认行为,导致输出通道数和预期不同。 - 想直接显示 HSV 原图,但没有先把它转换回 BGR 或拆通道查看。
- 把灰度图当成三通道图继续处理,没有先做
GRAY2BGR。 - 误以为所有颜色空间转换都只是“换个名字”,实际上很多转换会改变通道含义。
9. 进阶扩展
- 可以把
CvtColor和InRange结合起来做颜色分割。 - 可以先
BGR2HSV,再只取 H 通道做颜色筛选。 - 可以结合
Split/Merge,单独处理某个颜色通道。 - 可以把
BGR2GRAY作为图像预处理步骤,再接阈值、边缘和形态学操作。
10. 小结
Cv2.CvtColor是颜色空间转换的基础函数。只要记住三点就够了:
code决定转换方向和输出通道数。dstCn默认自动推导,但必要时也可以显式指定。- 很多视觉算法都先从
BGR2GRAY或BGR2HSV开始。
11. 相关链接
- WPF 教学控件:Cv2CvtColorControl.xaml.cs
- 样例实现:CvtColorSample.cs
- 官方文档源码位置:OpenCvSharp/Cv2/Cv2_imgproc.cs:2450
