色彩转换
这里我们把从mipi摄像头读取到的NV12数据, 使用RGA转换成BGR格式。
首先, 确保DMA buffer能正常使用, 详细请查看RGA DMA.
1. RGA NV12转BGR
使用DMA buffer后, 直接传递其handle, 代码如下:
- src_fd, 输入图片DMA句柄。
- src_size, 输入DMA大小。
- dst_fd, 转换后输出DMA句柄。
- dst_size, 输出DMA大小。
- width, 输入图片的宽。
- height, 输入图片的高。
int rga_nv12_fd_to_bgr_fd(int src_fd, int src_size, int dst_fd, int dst_size, int width, int height) {
// 计算对齐后的 wstride(水平 stride)
int wstride = (width + 15) & ~15; // 对齐到 16 像素
rga_buffer_handle_t src_handle = importbuffer_fd(src_fd, src_size);
rga_buffer_handle_t dst_handle = importbuffer_fd(dst_fd, dst_size);
if (!src_handle || !dst_handle) {
if (src_handle) releasebuffer_handle(src_handle);
if (dst_handle) releasebuffer_handle(dst_handle);
cerr << "importbuffer_fd failed\n";
return -1;
}
// 使用 wrapbuffer_handle 初始化基本字段(width, height, fd, handle 等)
rga_buffer_t src = wrapbuffer_handle(src_handle, width, height, RK_FORMAT_YCbCr_420_SP);
rga_buffer_t dst = wrapbuffer_handle(dst_handle, width, height, RK_FORMAT_BGR_888);
src.wstride = wstride; // 水平行跨距(Y 和 UV 平面都用这个)
src.hstride = height; // 垂直 stride,通常等于 height(除非特殊对齐要求)
dst.wstride = wstride;
dst.hstride = height;
// 检查参数
int ret = imcheck(src, dst, {}, {});
if (IM_STATUS_NOERROR != ret) {
cerr << "imcheck error: " << imStrError((IM_STATUS)ret) << endl;
releasebuffer_handle(src_handle);
releasebuffer_handle(dst_handle);
return -1;
}
// 执行颜色转换
ret = imcvtcolor(src, dst, RK_FORMAT_YCbCr_420_SP, RK_FORMAT_BGR_888);
if (ret != IM_STATUS_SUCCESS) {
cerr << "imcvtcolor failed: " << imStrError((IM_STATUS)ret) << endl;
releasebuffer_handle(src_handle);
releasebuffer_handle(dst_handle);
return -1;
}
// 释放 handle(DMA-BUF 引用不受影响)
releasebuffer_handle(src_handle);
releasebuffer_handle(dst_handle);
return 0;
}
2. V4L2 + RGA demo
使用V4L2获取mipi摄像头的NV12数据, 再把NV12使用RGA转换成BGR, 最后使用OpenCV显示到屏幕, 完整的demo请查看V4L2-CAMERA。
|-----------| RGA |----------|
| NV12 data | ----> | BGR data | ----> RKNN or X11...
|-----------| |----------|
也可以从此处下载完整的代码。