how capture frame then save it to .yuv file(422)

asked 2018-08-23 08:41:12 -0600

Droit gravatar image

updated 2018-08-23 08:44:40 -0600

berak gravatar image

Hi all:

my platform is win10 64bits+vs2017+opencv3.4.1

i use VideoCapture read frame in from camera and save frame as .png file .

that's ok.

but how can i read frame in then save frame as .yuv file(422)?

i have try code but show

"OpenCV: FFMPEG: tag 0x30323449/'I420' is not supported with codec id 14 and format 'rawvideo / raw video' VideoWriter has created."

is FFMPEG codec wrong or my code got problem?my code as below

many many thanks for you read it.

#include "opencv/cv.h"
#include "opencv/highgui.h"
#include "opencv2/opencv.hpp"
#include <iostream>


using namespace std;
using namespace cv;

CvVideoWriter* video = NULL;
FILE* pFile;


IplImage* RgbToYUV420(IplImage* pImage)
{

    cout << "width:" << pImage->width << "  height:" << pImage->height << 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;
    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);



            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;
            pRgbBuf += 3;




            if (i % 2 == 0 && j % 2 == 0)
            {

                *(pVBuf++) = v;
                *(pUBuf++) = u;
            }
        }



    fwrite(pYUVBuf, 1, yuvSize, pFile);


    pImage->dataOrder=1;*/


    return pImage;
}



int main(int argc, char** argv)
{
    CvCapture* capture = 0;
    IplImage* frame = 0;
    int frameWidth = 640;
    int frameHeight = 480;
    capture = cvCaptureFromCAM(1);
    video = cvCreateVideoWriter("out.yuv", CV_FOURCC('I', '4', '2', '0'), 25,
    cvSize(frameWidth, frameHeight));
    if (video) 
    {
        cout << "VideoWriter has created." << endl;
    }
    fopen_s(&pFile, "yuvvideo.yuv", "wb");
    int fps = 25; 
    //double fps = cvGetCaptureProperty(capture,CV_CAP_PROP_FPS); 


    CvVideoWriter* writer = 0;
    int isColol = 1;
    int frameW = 320;
    int frameH = 240;
    int n = 1;
    writer = cvCreateVideoWriter("out.avi", CV_FOURCC('M', 'P', '4', '2'), fps, cvSize(frameW, frameH), isColol);


    cvNamedWindow("webcam", 1);


    //for(int i=0;i<50;i++) //2秒
    for (;;) 
    {
        frame = cvQueryFrame(capture);


        cvWriteFrame(writer, frame);


        cvShowImage("webcam", frame); 
        frame = RgbToYUV420(frame);
        n = cvWriteFrame(video, frame);

        CAP_PROP_CONVERT_RGB
        cvWaitKey(1000 / fps);
    }


    cvReleaseVideoWriter(&writer);
    cvReleaseImage(&frame);
    cvReleaseCapture(&capture);
    cvDestroyWindow("webcam");
    return 0;
}
edit retag flag offensive close merge delete

Comments

opencv moved to c++ in 2010 already. the c-api is no more maintained, and you MUST NOT use it.

berak gravatar imageberak ( 2018-08-23 08:45:40 -0600 )edit

you means it can't work after 2010 because no c-api to use convert frame to .yuv file?

Droit gravatar imageDroit ( 2018-08-23 08:55:00 -0600 )edit