opencv視頻採集rgb to yuv

// ConsoleApplication2.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <opencv2\opencv.hpp> using namespace cv; using namespace std; FILE* pFile; IplImage* convert(IplImage* pImage) { int nWidth=pImage->width; int nHeight=pImage->height; IplImage* yimg = cvCreateImage(cvSize(nWidth, nHeight),IPL_DEPTH_8U,3);       //IplImage* uimg = cvCreateImageHeader(cvSize(nWidth/2, nHeight/2),IPL_DEPTH_8U,1);       //IplImage* vimg = cvCreateImageHeader(cvSize(nWidth/2, nHeight/2),IPL_DEPTH_8U,1);   cvCvtColor(pImage,yimg,CV_BGR2YUV); cout<<"bgr:"<<pImage->nSize<<" "<<pImage->channelSeq<<"  "<<pImage->dataOrder<<"  "<<pImage->depth<<"  "<<pImage->imageSize<<" "<<pImage->nChannels<<" "<<pImage->widthStep<<" "<<pImage->origin<<endl; cout<<"yuv:"<<yimg->nSize<<" "<<yimg->channelSeq<<"  "<<yimg->dataOrder<<"  "<<yimg->depth<<"  "<<yimg->imageSize<<" "<<yimg->nChannels<<" "<<yimg->widthStep<<" "<<yimg->origin<<endl; return yimg; } IplImage* RgbToYUV420(IplImage* pImage) { //cout<<"number of channels:"<<pImage->nChannels<<"  width step:"<<pImage->widthStep<<endl; cout<<"width:"<<pImage->width<<"  height:"<<pImage->height<<endl; //cout<<"order of data:"<<pImage->dataOrder<<endl; //cout<<"channel sequence:"<<pImage->channelSeq<<endl;*/ int width=pImage->width; int height=pImage->height; int yuvSize=width*height*3/2; char* pRgbBuf=pImage->imageData; char* pYBuf,*pUBuf,*pVBuf; char* pYUVBuf; pYUVBuf=(char*)malloc(yuvSize); pYBuf=pYUVBuf; memset(pYBuf,0,yuvSize); //pUBuf=pYBuf+width*height; //yuv格式按YUV排列 pUBuf=pYBuf+width*height; pVBuf=pUBuf+width*height/4; unsigned char r,g,b; unsigned char y,u,v;      for(int i=0;i<height;i++) for(int j=0;j<width;j++) { b=*(pRgbBuf); g=*(pRgbBuf+1); r=*(pRgbBuf+2); /*y = (unsigned char)(  0.299* r + 0.587* g +  0.114 * b )   ;                         u = (unsigned char)( -0.169 * r -  0.332 * g + 0.500 * b + 128)  ;                         v = (unsigned char)( 0.500 * r +0.419 * g -  0.0813 * b + 128);  */ //這纔是正確的公式???? y=uchar(0.257*r + 0.504*g + 0.098*b + 16);  u=uchar(-0.148*r - 0.291*g + 0.439*b + 128); v=uchar(0.439*r - 0.368*g - 0.071*b + 128); /*y=0.299*r + 0.587*g + 0.114*b;             u=(r-y)*0.713 + 128;             v=(b-y)*0.564 + 128;*/ if(y>255)y=255; else if(y<0)y=0; if(u>255)u=255; else if(u<0)u=0; if(v>255)v=255; else if(v<0)v=0; *(pYBuf++)=y; /**(pVBuf++)=v; *(pUBuf++)=u;*/ pRgbBuf+=3; /**(pRgbBuf++)=y; *(pRgbBuf++)=v; *(pRgbBuf++)=u;*/ if(i%2==0&&j%2==0) { //對uv取樣 *(pVBuf++)=v; *(pUBuf++)=u; } } //pImage->imageData=pYUVBuf; /*IplImage* yimg = cvCreateImageHeader(cvSize(width, height),IPL_DEPTH_8U,1);   cvSetData(yimg,pYUVBuf,width);*/ //pImage->imageSize=yuvSize; //fprintf(pFile,"%s",pYUVBuf); fwrite(pYUVBuf,1,yuvSize,pFile); //pImage->imageData=pYBuf; //pImage->imageDataOrigin=pYBuf; /*strcpy_s(pImage->channelSeq,"YVU"); pImage->dataOrder=1;*/ return pImage; } void JPG2YUV(IplImage* pImage) {     unsigned char yBuffer[640*480];     IplImage *y=cvCreateImageHeader(cvSize(640,480),IPL_DEPTH_8U,1);     y->imageData=(char*)&yBuffer[0];     y->widthStep=640;     y->origin=IPL_ORIGIN_TL;          unsigned char uBuffer[640*480/4];     IplImage *u=cvCreateImageHeader(cvSize(640/2,480/2),IPL_DEPTH_8U,1);     u->imageData=(char*)&uBuffer[0];     u->widthStep=640/2;     u->origin=IPL_ORIGIN_TL;          unsigned char vBuffer[640*480/4];     IplImage *v=cvCreateImageHeader(cvSize(640/2,480/2),IPL_DEPTH_8U,1);     v->imageData=(char*)&vBuffer[0];     v->widthStep=640/2;     v->origin=IPL_ORIGIN_TL;          IplImage *uOrigin=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);     IplImage *vOrigin=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);          FILE *yuv; fopen_s(&yuv,"frame.yuv","a");          //for (int i=0;i<263;i++) {         //char loadname[200];         //sprintf(loadname,imageFilename,i);             IplImage *frame=pImage;       //  printf("%d start\n",i);         cvCvtColor(frame,frame,CV_BGR2YUV);         cvSplit(frame,y,uOrigin,vOrigin,NULL);         cvResize(uOrigin,u);         cvResize(vOrigin,v);         fwrite(yBuffer,1,640*480,yuv);         fwrite(uBuffer,1,640*480/4,yuv);         fwrite(vBuffer,1,640*480/4,yuv);         //printf("%d done\n",i);       //  cvReleaseImage(&frame);             // }          fclose(yuv); } int main() { int frameWidth=320; int frameHeight=240; IplImage* pSaveFrame=NULL;  //CvCapture* capture=cvCaptureFromAVI("camera.avi"); CvCapture* capture=cvCaptureFromCAM(-1); cvSetCaptureProperty (capture, CV_CAP_PROP_FRAME_WIDTH, frameWidth);//設置視頻流的幀寬度 cvSetCaptureProperty (capture, CV_CAP_PROP_FRAME_HEIGHT, frameHeight);//設置視頻流的幀高度   CvVideoWriter* video=NULL; IplImage* frame=NULL; //char filename[20]; int i=0; //int p[3];    //  p[0] = CV_IMWRITE_JPEG_QUALITY;    //  p[1] = 10;  //質量值    //  p[2] = 0;   int n; if(!capture) //若是不能打開攝像頭給出警告 { cout<<"Can not open the camera."<<endl; return -1; } else { frame=cvQueryFrame(capture); //首先取得攝像頭中的一幀 video=cvCreateVideoWriter("camera.yuv",CV_FOURCC('I','4','2','0'),15, cvSize(frameWidth,frameHeight)); //建立CvVideoWriter對象並分配空間 //保存的文件名爲camera.avi,編碼要在運行程序時選擇,大小就是攝像頭視頻的大小,幀頻率是15,CV_FOURCC(I,4,2,0)表示yuv420編碼 if(video) //若是能建立CvVideoWriter對象則代表成功 { cout<<"VideoWriter has created."<<endl; } cvNamedWindow("Camera Video",1); //新建一個窗口 fopen_s(&pFile,"yuvvideo.yuv","wb"); while(1) { frame=cvQueryFrame(capture); //從CvCapture中得到一幀   if(!frame) { cout<<"Can not get frame from the capture."<<endl; break; } n=cvWriteFrame(video,frame); //判斷是否寫入成功,若是返回的是1,表示寫入成功 cout<<n<<endl; //frame=convert(frame); frame=RgbToYUV420(frame); //JPG2YUV(frame); cvShowImage("Camera Video",frame); //顯示視頻內容的圖片 //pSaveFrame=cvCreateImage(cvSize(frame->width,frame->height),frame->depth,frame->nChannels);  //sprintf_s(filename,"%d.jpg",i); //i++;  //     cvResize(frame,pSaveFrame,CV_INTER_LINEAR);      //        cvSaveImage(filename,pSaveFrame,p);      //        cvReleaseImage(&pSaveFrame);  if(cvWaitKey(1)>0) break; //有其餘鍵盤響應,則退出 } fclose(pFile); cvReleaseVideoWriter(&video); cvReleaseCapture(&capture); cvDestroyWindow("Camera Video"); } return 0; }
相關文章
相關標籤/搜索