OpenCV读取YUV420p文件并转换为Mat类型

时间:2021-07-16 08:45:26

参考文章:

http://blog.csdn.net/gxiaob/article/details/9718071


这里直接封装成了 Mat类型,增加了YUV400格式的转换:


void conv_yuv420_to_mat(Mat &dst, unsigned char* pYUV420, int width, int height)
{
if (!pYUV420) {
return;
}

IplImage *yuvimage,*rgbimg,*yimg,*uimg,*vimg,*uuimg,*vvimg;

int nWidth = width;
int nHeight = height;
rgbimg = cvCreateImage(cvSize(nWidth, nHeight),IPL_DEPTH_8U,3);
yuvimage = cvCreateImage(cvSize(nWidth, nHeight),IPL_DEPTH_8U,3);

yimg = cvCreateImageHeader(cvSize(nWidth, nHeight),IPL_DEPTH_8U,1);
uimg = cvCreateImageHeader(cvSize(nWidth/2, nHeight/2),IPL_DEPTH_8U,1);
vimg = cvCreateImageHeader(cvSize(nWidth/2, nHeight/2),IPL_DEPTH_8U,1);

uuimg = cvCreateImage(cvSize(nWidth, nHeight),IPL_DEPTH_8U,1);
vvimg = cvCreateImage(cvSize(nWidth, nHeight),IPL_DEPTH_8U,1);

cvSetData(yimg,pYUV420, nWidth);
cvSetData(uimg,pYUV420+nWidth*nHeight, nWidth/2);
cvSetData(vimg,pYUV420+long(nWidth*nHeight*1.25), nWidth/2);
cvResize(uimg,uuimg,CV_INTER_LINEAR);
cvResize(vimg,vvimg,CV_INTER_LINEAR);

cvMerge(yimg,uuimg,vvimg,NULL,yuvimage);
cvCvtColor(yuvimage,rgbimg,CV_YCrCb2RGB);

cvReleaseImage(&uuimg);
cvReleaseImage(&vvimg);
cvReleaseImageHeader(&yimg);
cvReleaseImageHeader(&uimg);
cvReleaseImageHeader(&vimg);

cvReleaseImage(&yuvimage);

dst = Mat(rgbimg, true);
cvReleaseImage(&rgbimg);
}

void conv_yuv400_to_mat(Mat &dst, unsigned char* pYUV400, int nWidth, int nHeight, int bit_depth)
{
IplImage *yimg;

if (!pYUV400) {
return;
}

if (bit_depth == 8) {
yimg = cvCreateImageHeader(cvSize(nWidth, nHeight), IPL_DEPTH_8U, 1);
} else {
yimg = cvCreateImageHeader(cvSize(nWidth, nHeight), IPL_DEPTH_16U, 1);
}

cvSetData(yimg, pYUV400, nWidth);

dst = Mat(yimg, true);
cvReleaseImageHeader(&yimg);
}


/* ---------------------------------------------------------------------------
*/
void DisplayYUV420(const char *s_path, int img_w, int img_h)
{
printf("yuv file img_w: %d, img_h: %d \n", img_w, img_h);

FILE* pFileIn = fopen(s_path, "rb");
int bufLen = img_w * img_h * 3 / 2;
unsigned char* pYuvBuf = new unsigned char[bufLen];
int iCount = 0;


for (iCount = 0; iCount < 200; iCount++) {
Mat rgbImg;
fread(pYuvBuf, bufLen * sizeof(unsigned char), 1, pFileIn);

conv_yuv420_to_mat(rgbImg, pYuvBuf, img_w, img_h);

cv::imshow("img", rgbImg);
cv::waitKey(1);

printf("%d \n", iCount);
}

delete[] pYuvBuf;
fclose(pFileIn);
}

/* ---------------------------------------------------------------------------
*/
void DisplayYUV400(const char *s_path, int img_w, int img_h, int bit_depth)
{
printf("yuv file img_w: %d, img_h: %d \n", img_w, img_h);

FILE* pFileIn = fopen(s_path, "rb");
int size_of_pixel = (bit_depth <= 8) ? 1 : 2;
int bufLen = img_w * img_h * size_of_pixel;
unsigned char* pYuvBuf = new unsigned char[bufLen];
int iCount = 0;


for (iCount = 0; iCount < 200; iCount++) {
Mat rgbImg;
fread(pYuvBuf, bufLen * sizeof(unsigned char), 1, pFileIn);

conv_yuv400_to_mat(rgbImg, pYuvBuf, img_w, img_h, bit_depth);

cv::imshow("img", rgbImg);
cv::waitKey(0);

printf("%d \n", iCount);
}

delete[] pYuvBuf;
fclose(pFileIn);
}