1、YUV和RGB格式分析(这里有清楚的解释:http://www.cnblogs.com/silence-hust/p/4465354.html),这里不讲原理,只是实现yuv422转RGB(opencv).
2、YUV422ToRGB.h
#pragma once
#define INT_TO_UCHAR(V) (unsigned char)((unsigned)V <= 255 ? V : V > 0 ? 255 : 0)
class YUV422ToRGB
{
public:
YUV422ToRGB(void);
~YUV422ToRGB(void);
public:
void Yuv2RgbImage(char *pImageDataBuf, bool bSwitchRedBlue, unsigned char *pYuvDataBuf);
};
3、YUV422ToRGB.cpp
#include "YUV422ToRGB.h"
#include
using namespace std;
YUV422ToRGB::YUV422ToRGB(void)
{
}
YUV422ToRGB::~YUV422ToRGB(void)
{
}
/*************************************************************
函数名称 :Yuv2RgbImage
函数功能 : 获取图片
输出参数 :image_data_buf :图片数据buf,buf大小固定为1920*1080*3
输入参数 :bSwitchRedBlue true:转成BGR false:转成RGB
用法 :IplImage* Img = cvCreateImage(cvSize(1920, 1080), 8, 3);
readImageromCamera(Img->imageData);
*************************************************************/
void YUV422ToRGB::Yuv2RgbImage(char *pImageDataBuf, bool bSwitchRedBlue, unsigned char *pYuvDataBuf)
{
unsigned char* pImagebuf = (unsigned char *)pYuvDataBuf;
int i, j;
for(j = 0; j < 1080; j++, pYuvDataBuf += 3840)
{
for (i = 0; i < 2 * 1920; i += 4, pImageDataBuf += 6)
{
int u = (int)(pYuvDataBuf[i + 3]) - 128;
int v = (int)(pYuvDataBuf[i + 1]) - 128;
int ruv = (1 << 19) + 2130771 * v;
int guv = (1 << 19) - 413812 * v - 608826 * u;
int buv = (1 << 19) + 1195253 * u;
if (bSwitchRedBlue)
{
int temp = ruv;
ruv = buv;
buv = temp;
}
int y00 = max(0, (int)(pYuvDataBuf[i + 0])) << 20;
pImageDataBuf[0] = INT_TO_UCHAR((y00 + ruv) >> 20);
pImageDataBuf[1] = INT_TO_UCHAR((y00 + guv) >> 20);
pImageDataBuf[2] = INT_TO_UCHAR((y00 + buv) >> 20);
int y01 = max(0, (int)(pYuvDataBuf[i + 2])) << 20;
pImageDataBuf[3] = INT_TO_UCHAR((y01 + ruv) >> 20);
pImageDataBuf[4] = INT_TO_UCHAR((y01 + guv) >> 20);
pImageDataBuf[5] = INT_TO_UCHAR((y01 + buv) >> 20);
}
}
pYuvDataBuf = pImagebuf;
}
4、main.cpp
#include
#include
#include
#include "YUV422ToRGB.h"
int main(int argc, char *argv[])
{
YUV422ToRGB *pYuvToRgb = new YUV422ToRGB;
int iYuvDataBufSize = 1920 * 1080 * 2;
char *pYuvDataBuf = new char[iYuvDataBufSize];
//从文件读取YUV数据到buf
FILE *fp = fopen("./1.yuv", "r");
fread(pYuvDataBuf, iYuvDataBufSize, 1, fp);
fclose(fp);
//YUV 转成 RGB
IplImage *pSrcImage = cvCreateImage(cvSize(1920, 1080), 8, 3);
cvZero(pSrcImage);
pYuvToRgb->Yuv2RgbImage(pSrcImage->imageData, false, (unsigned char*)pYuvDataBuf);
cvSaveImage("./test.bmp", pSrcImage);
cvNamedWindow("YUV422ToRGB");
cvShowImage("YUV422ToRGB", pSrcImage);
cvWaitKey(0);
cvReleaseImage(&pSrcImage);
delete pYuvToRgb;
delete[] pYuvDataBuf;
return 0;
}