#include
#include
using namespace cv;
using namespace std;
//#include <>
#define nWidth 640
#define nHeight 480
#define FrameSize nWidth*nHeight*3/2
#define YUV2R(y, u, v) ({ \
int r = (y) + ((((v) - 128) * 1436) >> 10); r > 255 ? 255 : r < 0 ? 0 : r; })
#define YUV2G(y, u, v) ({ \
int g = (y) - ((((u) - 128) * 352 + ((v) - 128) * 731) >> 10); g > 255 ? 255 : g < 0 ? 0 : g; })
#define YUV2B(y, u, v) ({ \
int b = (y) + ((((u) - 128) * 1814) >> 10); b > 255 ? 255 : b < 0 ? 0 : b; })
#define CLIP(color) (unsigned char)(((color) > 0xFF) ? 0xff : (((color) < 0) ? 0 : (color)))
void v4lconvert_yuv420_to_bgr24__(const unsigned char *src, unsigned char *dest,int width, int height, int yvu)
{
int i, j;
const unsigned char *ysrc = src;
const unsigned char *usrc, *vsrc;
if (yvu)
{
vsrc = src + width * height;
usrc = vsrc + (width * height) / 4;
} else {
usrc = src + width * height;
vsrc = usrc + (width * height) / 4;
}
for (i = 0; i < height; i++) {
for (j = 0; j < width; j += 2) {
#if 1 /* fast slightly less accurate multiplication free code */
int u1 = (((*usrc - 128) << 7) + (*usrc - 128)) >> 6;
int rg = (((*usrc - 128) << 1) + (*usrc - 128) +
((*vsrc - 128) << 2) + ((*vsrc - 128) << 1)) >> 3;
int v1 = (((*vsrc - 128) << 1) + (*vsrc - 128)) >> 1;
*dest++ = CLIP(*ysrc + u1);
*dest++ = CLIP(*ysrc - rg);
*dest++ = CLIP(*ysrc + v1);
ysrc++;
*dest++ = CLIP(*ysrc + u1);
*dest++ = CLIP(*ysrc - rg);
*dest++ = CLIP(*ysrc + v1);
#else
*dest++ = YUV2B(*ysrc, *usrc, *vsrc);
*dest++ = YUV2G(*ysrc, *usrc, *vsrc);
*dest++ = YUV2R(*ysrc, *usrc, *vsrc);
ysrc++;
*dest++ = YUV2B(*ysrc, *usrc, *vsrc);
*dest++ = YUV2G(*ysrc, *usrc, *vsrc);
*dest++ = YUV2R(*ysrc, *usrc, *vsrc);
#endif
ysrc++;
usrc++;
vsrc++;
}
/* Rewind u and v for next line */
if (!(i & 1)) {
usrc -= width / 2;
vsrc -= width / 2;
}
}
}
int main()
{
/*IplImage *img = cvLoadImage("D:\\workspace\\cv_yun\\DSC_1598.JPG");
cvNamedWindow("a");
cvShowImage("a",img);
cvWaitKey(0);
*/
FILE *f ;
if(!(f = fopen("c:\\YUV420.yuv","rb")))
{
printf("file open error!");
}
// calculate the frame num
fseek(f, 0, SEEK_END);
int frame_count = 0;
long file_size = 0;
frame_count = (int) ((int)ftell(f)/((nWidth * nHeight * 3) / 2)); // ftell 用于求文件大小
printf("frame num is %d \n", frame_count);
printf("file length is %d",ftell(f));
fseek(f, 0, SEEK_SET);//文件内位置定位到文件头
//IplImage *img = cvCreateImage(cvSize(352,288),IPL_DEPTH_8U,1);
//IplImage *grey;
for (int i=0;i<100;i++)
{
IplImage *yimg = cvCreateImage(cvSize(nWidth, nHeight),IPL_DEPTH_8U,1);
//IplImage *uimg = cvCreateImageHeader(cvSize(nWidth/2, nHeight/2),IPL_DEPTH_8U,1);
//IplImage *vimg = cvCreateImageHeader(cvSize(nWidth/2, nHeight/2),IPL_DEPTH_8U,1);
//----------------------------------------------------------------------实现读取一个文件 显示照片
unsigned char *pBuf = new unsigned char[nWidth*nHeight*3/2];
fread(pBuf, 1, (nWidth * nHeight * 3) / 2, f);// nWidth*nHeight*3/2 means 本程序使用 yuv:4:2:0 yuv分为 Y Cb Cr 三部分
cvSetData(yimg, pBuf, nWidth);
cvNamedWindow("a");
cvShowImage("a", yimg);
cvWaitKey( 1 );
unsigned char *PRGB = new unsigned char[nWidth*nHeight*3];
PRGB=(unsigned char*)malloc(nWidth*nHeight*3*sizeof(unsigned char));
v4lconvert_yuv420_to_bgr24__(pBuf, PRGB,nWidth, nHeight, 24);
Mat YUVDATA(Size(nWidth,nHeight),CV_8UC3,Scalar(0));
memcpy(YUVDATA.data,PRGB,nWidth*nHeight*3);
cvtColor(YUVDATA,YUVDATA,CV_BGR2RGB);
imshow("YUVDATA",YUVDATA);
waitKey(1);
}
//----------------------------------------------------------------------读取yuv文件的y部分 类似于播放器效果
/*unsigned char *pBuf = new unsigned char[nWidth*nHeight*3/2];
int pos = 0;
for(int i = 0; i