// 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;
}