某些特定场合我们会经常遇到yuv420格式的视频文件,这种视频帧无法直接用于opencv,故而,需要进行格式转换;幸运的是,opencv提供了rgb到yuv420的格式转换函数;下面给出基本用法;
函数1:读取avi格式的视频文件,转换成Yuv420格式,并写入文件;
void WriteYuv()
cv::VideoCapture vc;
bool flag = vc.open("S1000008.avi");
if (!flag)
printf("avi file open error \n");
system("pause");
exit(-1);
int frmCount = vc.get(CV_CAP_PROP_FRAME_COUNT);
frmCount -= 5;
printf("frmCount: %d \n", frmCount);
int w = vc.get(CV_CAP_PROP_FRAME_WIDTH);
int h = vc.get(CV_CAP_PROP_FRAME_HEIGHT);
int bufLen = w*h*3/2;
unsigned char* pYuvBuf = new unsigned char[bufLen];
FILE* pFileOut = fopen("result.yuv", "w+");
if (!pFileOut)
printf("pFileOut open error \n");
system("pause");
exit(-1);
printf("pFileOut open ok \n");
for (int i=0; i<frmCount; i++)
printf("%d/%d \n", i+1, frmCount);
cv::Mat srcImg;
vc>>srcImg;
cv::imshow("img", srcImg);
cv::waitKey(1);
cv::Mat yuvImg;
cv::cvtColor(srcImg, yuvImg, CV_BGR2YUV_I420);
memcpy(pYuvBuf, yuvImg.data, bufLen*sizeof(unsigned char));
fwrite(pYuvBuf, bufLen*sizeof(unsigned char), 1, pFileOut);
fclose(pFileOut);
delete[] pYuvBuf;
函数二,读取yuv420格式的文件,转换成cv::Mat格式,并予以显示:
void DisplayYUV()
int w = 1280;
int h = 720;
printf("yuv file w: %d, h: %d \n", w, h);
FILE* pFileIn = fopen("result.yuv", "rb+");
int bufLen = w*h*3/2;
unsigned char* pYuvBuf = new unsigned char[bufLen];
int iCount = 0;
for(int i=0; i<200; i++)
fread(pYuvBuf, bufLen*sizeof(unsigned char), 1, pFileIn);
cv::Mat yuvImg;
yuvImg.create(h*3/2, w, CV_8UC1);
memcpy(yuvImg.data, pYuvBuf, bufLen*sizeof(unsigned char));
cv::Mat rgbImg;
cv::cvtColor(yuvImg, rgbImg, CV_YUV2BGR_I420);
cv::imshow("img", yuvImg);
cv::waitKey(1);
printf("%d \n", iCount++);
delete[] pYuvBuf;
fclose(pFileIn);
某些特定场合我们会经常遇到yuv420格式的视频文件,这种视频帧无法直接用于opencv,故而,需要进行格式转换;幸运的是,opencv提供了rgb到yuv420的格式转换函数;下面给出基本用法;函数1:读取avi格式的视频文件,转换成Yuv420格式,并写入文件;void WriteYuv(){ cv::VideoCapture vc; bool flag = vc.ope
用海康采集卡做个项目 需要连续抓拍及缓冲图片 用SDK本身提供的图像抓拍太费时 调用间隔较小时导致画面卡顿现象;改用原始图像数据流回调函数RegisterImageStreamCallback进行抓图 但回调函数帧为YUV420格式 需要转成Bitmap才用用于显示及本地查看 在网上找了好多都是基于R Y+1 4075 V 128 G Y 0 3455 U 128 – 0 7169 V 128 B Y+1 779 U 128 公式运算且大多是C语言 改成C#后效率一直不高(尝试过消除浮点运算 查表法等) 后看到MSDN上的转换公式 http: msdn microsoft com en us library aa917087 aspx 后编写了此转换类库 转换一个D1帧 704 576 大约只需60ms左右 压缩包为Vs2010项目带使用示例 ">用海康采集卡做个项目 需要连续抓拍及缓冲图片 用SDK本身提供的图像抓拍太费时 调用间隔较小时导致画面卡顿现象;改用原始图像数据流回调函数RegisterImageStreamCallback进行抓图 但回调函数帧为YUV420格式 需要转成Bitmap
YUV420 -> Mat 可用于转换接受到的YUV视频源到OpenCV可以识别的数据
Mat myuv( Frame_Height + Frame_Height / 2, Frame_Width, CV_8UC1, (unsigned char *) YUV420_Image_Buffer);
cvtColor(myuv, mgMat, CV_YUV420p2RGB);
Mat -> YUV420 可用于OpenCV处理完视频信号后返回
cvtColor(mgMat, myuv,C.
1 sprintf(imagepath, "/mnt/md/test/mtcnn/images/%d.jpg", i);
4 printf("imagepath:%s\n", imagepath);
5 cv::Mat cv_img = cv::imread(imagepath, 3);
6 if (cv_img.empty())
8 fprin...
cv::
Mat 中除了可以保存BGR格式的数据外,还可以保存
YUV数据,可以通过
cv::
Mat imgBGR24, img
YUV;
cv::
cvtColor(imgBGR24, img
YUV,
cv::COLOR_BGR2
YUV_I
420);
来进行
转换,但是需要强调一点当
mat中保存为
YUV数据后,其中的rows和cols就不能用了,会发生变化
1、问题描述
cv::Mat保存RGB24或BRG24格式时,传入宽、高和格式类型CV_8UC3就行了;今天在创建cv::Mat用来保存YUV420P时,有点懵圈了,因为类型是CV_8UC1,直接传宽和高,只能保存Y分量。因此需要宽或者高乘以一个系数,才能保存完整。
一开始我将,这个系数1.5乘给了宽,并将宽width赋值给了行数rows:
cv::Mat yuv420p(width*3/2, h...
1.
YUV420 ->
Mat 可用于
转换接受到的
YUV视频源到Open
CV可以识别的数据
Mat m
yuv( Frame_Height + Frame_Height / 2, Frame_Width,
CV_8UC1, (unsigned char *)
YUV420_Image_Buffer);
cvtColor(m
yuv, mg
Mat,
CV_
YUV420p2RGB);
YUV420P,YUV420,YUV420SP 都是视频压缩格式中常用的 YUV 颜色编码方式。
YUV420P 指的是 YUV 色彩空间的一种,也称为 YUV 4:2:0 planar,其中的 Y、U、V 分别表示亮度(Luma)和色度(Chroma)的信号。它的特点是 Y 分量与 U、V 分量分开存储,即亮度和色度分别存储在不同的平面(plane)中。
YUV420 同样是 YUV 4:2:0 的一种,与 YUV420P 的区别在于 YUV420 中 Y 分量、U 分量、V 分量是按顺序交叉存储的,即 Y、U、V 依次排列,而不是分别存储在不同的平面中。
YUV420SP(YUV 4:2:0 semi-planar)是 YUV420P 和 YUV420 的一种结合,它也是按照 Y、U、V 的顺序存储的,但 U 分量和 V 分量是交叉存储的。
总的来说,YUV420P 中的亮度和色度分开存储,方便视频编解码器处理。而 YUV420 和 YUV420SP 中的 YUV 分量是交叉存储的,可以减少存储空间,但视频编解码器处理起来略微麻烦。