You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用OpenCV将BGR(cv::Mat)转换为NV12(cv::Mat)

OpenCV BGR转NV12/NV21实现方案

OpenCV官方目前没有提供直接转换NV12、NV21格式的内置flag,你可以通过手动拼接YUV通道的方式实现,具体逻辑和示例代码如下:

实现原理

NV12和NV21都属于YUV420SP格式,Y通道单独存储,U和V通道交叉打包存储,两者仅UV顺序有区别:

  • NV12:UV平面顺序为U在前、V在后
  • NV21:UV平面顺序为V在前、U在后

实现步骤

  • 先通过OpenCV内置的cv2.COLOR_BGR2YUV_I420参数将BGR图像转换为I420(YUV420P)格式,转换后的数据按Y平面、U平面、V平面的顺序连续存储
  • 拆分得到独立的Y、U、V三个通道,若原图尺寸为width*height,则Y通道长度为width*height,U、V通道长度均为width*height//4
  • 按目标格式要求交叉拼接U、V通道得到UV平面
  • 最后将Y平面和拼接完成的UV平面按顺序拼接,即可得到最终的NV12/NV21数据

示例代码(Python)

import cv2
import numpy as np

# BGR转NV12
def bgr_to_nv12(bgr_img):
    height, width = bgr_img.shape[:2]
    # 转I420格式
    i420 = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2YUV_I420)
    # 拆分Y/U/V通道
    y_channel = i420[:height, :]
    u_channel = i420[height : height + height//4, :].reshape(-1)
    v_channel = i420[height + height//4 : , :].reshape(-1)
    # 交叉拼接UV平面(U在前V在后)
    uv_plane = np.zeros(u_channel.size + v_channel.size, dtype=u_channel.dtype)
    uv_plane[0::2] = u_channel
    uv_plane[1::2] = v_channel
    uv_plane = uv_plane.reshape(height//2, width)
    # 拼接得到NV12
    nv12_data = np.vstack((y_channel, uv_plane))
    return nv12_data

# BGR转NV21
def bgr_to_nv21(bgr_img):
    height, width = bgr_img.shape[:2]
    i420 = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2YUV_I420)
    y_channel = i420[:height, :]
    u_channel = i420[height : height + height//4, :].reshape(-1)
    v_channel = i420[height + height//4 : , :].reshape(-1)
    # 交叉拼接UV平面(V在前U在后)
    uv_plane = np.zeros(u_channel.size + v_channel.size, dtype=u_channel.dtype)
    uv_plane[0::2] = v_channel
    uv_plane[1::2] = u_channel
    uv_plane = uv_plane.reshape(height//2, width)
    # 拼接得到NV21
    nv21_data = np.vstack((y_channel, uv_plane))
    return nv21_data

C++版本实现说明

C++版本逻辑和Python版本完全一致,先转换为I420格式,再拆分通道交叉拼接UV即可,无需依赖额外第三方组件。

内容的提问来源于stack exchange,提问作者yahuuu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 12:24:03