问题描述
做K230视觉开发的小伙伴们,是不是经常被图像格式转换搞得头大?YUV转RGB、RGB转YUV、色域空间调整…这些基础操作不仅繁琐,还容易踩坑!
今天就带大家吃透CanMV里的CSC模块(Color Space Conversion,色彩空间转换)——K230图像处理的“格式转换神器”,手把手教你从0到1玩转它,让图像格式转换又快又稳!

1、先搞懂:CSC模块到底是什么?
CSC是K230 CanMV平台专为2D色彩空间转换设计的模块,核心作用是:
✅ 实现不同色彩空间(如RGB/YUV/YCbCr)的快速转换
✅ 硬件级加速,转换效率远高于纯软件实现
✅ 无需依赖AI算力,轻量化适配K230的边缘计算场景
简单说:只要你在K230上做图像采集、显示、预处理,几乎都绕不开CSC模块——比如摄像头采集的YUV图像要转RGB才能显示,RGB图像要转YUV才能做编码,AI这边需要处理RGB888p格式,这些都能交给CSC一键搞定!
目前支持的转换格式:
static const k_pixel_format supported_format[] = {
PIXEL_FORMAT_RGB_565,
PIXEL_FORMAT_RGB_565_LE,
PIXEL_FORMAT_BGR_565,
PIXEL_FORMAT_BGR_565_LE,
PIXEL_FORMAT_RGB_888,
PIXEL_FORMAT_BGR_888,
PIXEL_FORMAT_ARGB_8888,
PIXEL_FORMAT_ARGB_1555,
PIXEL_FORMAT_ARGB_4444,
PIXEL_FORMAT_BGR_888_PLANAR,
PIXEL_FORMAT_RGB_888_PLANAR,
PIXEL_FORMAT_YVU_PLANAR_420,
PIXEL_FORMAT_YUV_SEMIPLANAR_420,
PIXEL_FORMAT_YVU_SEMIPLANAR_420,
PIXEL_FORMAT_YVU_PLANAR_444,
PIXEL_FORMAT_YUV_PACKAGE_444,
PIXEL_FORMAT_YUV_SEMIPLANAR_444,
PIXEL_FORMAT_YVU_SEMIPLANAR_444,
};
📝 手把手实操:CSC模块核心用法
1. 环境准备
- 硬件:K230开发板(CanMV固件已烧录)
- 软件:CanMV IDE / 串口终端(波特率115200)
- 依赖:确保CanMV固件版本≥V0.5.0(CSC模块核心功能已完善)
2. 核心API速览
SDK源码路径:
~/src/canmv/port/modules/modnonai2d.csc.c
DEMO路径:
/sdcard/examples/21-AI-With-Others/ai_uvc_hard_decode.py
官方文档中CSC模块的核心接口是 convert:
from nonai2d import CSC
csc = CSC(chn, fmt, max_width=1920, max_height=1080, buf_num=2)
result = csc.convert(frame, timeout_ms=1000, cvt=True)
csc.destroy()
注意:csc.convert 输入 frame 为 py_video_frame_info ,是 sensor.snapshot() 的输出
3 实战案例:YUV转RGB
需求:将UVC摄像头采集的YUV420SP格式图像,转换为RGB565格式并显示
# hardware Color Space Converter
csc = CSC(0, CSC.PIXEL_FORMAT_RGB_565)
。。。
while True:
clock.tick()
img = UVC.snapshot()
if img is not None:
img = csc.convert(img)
。。。
4.进阶玩法:巧用bind完成自动转换链路
上文的方案需逐帧提取数据并送入 CSC 模块处理,存在多次数据拷贝,导致处理效率降低。针对这一痛点,我们推出bind 模式—— 支持将 sensor、VDEC 等数据源与 CSC 模块直接绑定,实现数据自动格式转换。
示例如下:将 VDEC 与 CSC 模块通过 bind 功能绑定,可直接把 VDEC 输出的 YUV420 数据转换为 RGB888p 格式。
参考代码:
/sdcard/examples/21-AI-With-Others/face_detect_yunet_from_mp4.py
csc = CSC(2, CSC.PIXEL_FORMAT_RGB_888_PLANAR, buf_num=4)
。。。
#vb buffer初始化
MediaManager.init()
# 创建video decoder
vdec.create()
bind_info = vdec.bind_info(width=video_info.width, height=video_info.height,chn=vdec.get_vdec_channel())
Display.bind_layer(**bind_info, layer = Display.LAYER_VIDEO1)
vdec_link = MediaManager.link((VIDEO_DECODE_MOD_ID, VDEC_DEV_ID, vdec.get_vdec_channel()), (NONAI_2D_CSC_MOD_ID, 0, 2))
vdec.start()
3、总结&拓展
CSC模块是K230 CanMV视觉开发的“基础中的基础”,掌握它能搞定:
✅ 摄像头图像格式适配显示
✅ 图像预处理前的格式转换
✅ 不同设备间的图像数据交互
官网参考资料:
https://www.kendryte.com/k230_canmv/zh/main/zh/api/mpp/nonai2d_csc.html
💬互动话题
你在K230开发中遇到过哪些图像格式转换的坑?评论区聊聊~