一、简介
YUV,是一种颜色编码方法。常使用在各个视频处理组件中。“Y”表示明亮度(Luminance、Luma),“U” 和 “V” 则是色度、浓度(Chrominance、Chroma)。
NV21 和 NV12 是 YUV 的两种具体编码形式,以一个 2*2 像素大小的图为例,则排列如下:
NV21:YYYYVUVU
NV12:YYYYUVUV
二、求 nv21/nv12 各通道均值
这里以 nv21 为例,nv12 的话仅调换 Y、U 的位置即可。
void get_yuv_average(const cv_image_t* image_in, double* Y_mean, double* U_mean, double* V_mean) {
if (image_in == NULL || image_in->pixel_format != CV_PIX_FMT_NV21) {
return; // 检测输入参数
}
if ((image_in->width % 2 != 0) || (image_in->height % 2 != 0)) {
return; // 宽高必须为偶数
}
unsigned char* nv21_ptr = (unsigned char*) image_in->data;
int pixel_count = image_in->width * image_in->height;
// 计算各通道总值
double Y_sum = 0, U_sum = 0, V_sum = 0;
for (int i = 0; i < pixel_count; ++i) {
Y_sum += *(nv21_ptr + i);
}
for (int i = 0; i < pixel_count / 2; i += 2) {
V_sum += *(nv21_ptr + pixel_count + i);
U_sum += *(nv21_ptr + pixel_count + i + 1);
}
// 计算各通道均值,注意 U 和 V 是使用 U_sum 或 V_sum 除以 (pixel_count / 4)
Y_mean = Y_sum / pixel_count;
U_mean = U_sum * 4 / pixel_count;
V_mean = V_sum * 4 / pixel_count;
}
结构体:
typedef struct cv_image_t {
unsigned char *data; ///< 图像数据指针
cv_pixel_format pixel_format; ///< 像素格式
int width; ///< 宽度(以像素为单位)
int height; ///< 高度(以像素为单位)
} cv_image_t;
typedef enum {
CV_PIX_FMT_GRAY8, ///< Y 1 8bpp ( 单通道8bit灰度像素 )
CV_PIX_FMT_YUV420P, ///< YUV 4:2:0 12bpp ( 3通道, 一个亮度通道, 另两个为U分量和V分量通道, 所有通道都是连续的 )
CV_PIX_FMT_NV12, ///< YUV 4:2:0 12bpp ( 2通道, 一个通道是连续的亮度通道, 另一通道为UV分量交错 )
CV_PIX_FMT_NV21, ///< YUV 4:2:0 12bpp ( 2通道, 一个通道是连续的亮度通道, 另一通道为VU分量交错 )
CV_PIX_FMT_BGRA8888, ///< BGRA 8:8:8:8 32bpp ( 4通道32bit BGRA 像素 )
CV_PIX_FMT_BGR888, ///< BGR 8:8:8 24bpp ( 3通道24bit BGR 像素 )
CV_PIX_FMT_RGBA8888, ///< RGBA 8:8:8:8 32bpp ( 4通道32bit RGBA 像素 )
CV_PIX_FMT_RGB888, ///< RGB 8:8:8 24bpp ( 3通道24bit RGB 像素 )
CV_PIX_FMT_GRAY16, ///< 特殊图像格式,并不提供旋转以及到其他格式的转换等
CV_PIX_FMT_RGB565, ///< RGB 5:6:5 16bpp,只在fastcv开启时支持从RGB565转BGR和GRAY,目前仅支持android arm平台
CV_PIX_FMT_ABGR8888 ///< ABGR 8:8:8:8 32bpp ( 4通道32bit ABGR 像素 ),目前仅支持android arm平台
} cv_pixel_format;