Как сохранить выходное видео в файл в OpenCV

Я хочу сохранить выходное видео в файл, а не показывать его, и попытался использовать cvcaptureimage, но все еще не смог получить результат

#include <highgui.h>

int main(int argc, char *argv[])
{
    // Create a "Capture" object from 1st command line argument
    CvCapture *video = cvCaptureFromFile(argv[1]);
    // this is the structure that will store the frames
    IplImage *frame = NULL;
    // create a window to display the video
    cvNamedWindow("Video", CV_WINDOW_AUTOSIZE);
    // get the next frame
    while (frame = cvQueryFrame(video) )
    {
        // display it in the window we created
        cvShowImage("Video", frame);
        // wait 1000/fps milliseconds
        cvWaitKey((int)(1000/cvGetCaptureProperty(video, CV_CAP_PROP_FPS)));
        //reading into .avi file
        CvCapture*capture=0  
        capture=cvcreateFileCapture(arg[1]);
      if(!capture)
        {
           // intiate the video read
            IpLImage *bgr_frame=cvQueryFrame(capture);
            double fps=cvGetCaptureProperty(capture,CV_CAP_PROP_FPS);
         } 
    }
}

Могу ли я узнать ошибку, которую я повторяю в своем коде?

Ответ 1

Я знаю, что это довольно старый, но я не могу согласиться с этим утверждением о OSX.

Вы можете легко создавать и компилировать FFMPEG на OSX. Нет необходимости использовать QTKIT/Quicktime. Я фактически пишу видео на OSX без проблем.

Другое предложение - использовать новые структуры OpenCV 2.0+ вместо использования устаревших. (Используйте Mat вместо IplImage/cvMat, используйте VideoWriter и VideoCapture.)

Mat image;
VideoCapture capture;
VideoWriter out;

capture = VideoCapture(-1);
image << capture;

out.write(image);

Ответ 2

Если вам нужен код ссылки, this и this, чтобы вы начали.

В любом случае, приведенный ниже код отображает видео с веб-камеры. Если вы подойдете ближе, вы увидите, что в окне отображается преобразование из цветного фрейма в оттенок серого, а оттенки серого отображаются в окне.

Рамка в оттенках серого также записывается в файл на диске с именем out.avi. Вы должны знать, что этот код не будет работать в Mac OS X с OpenCV 2.1 просто потому, что OpenCV необходимо скомпилировать с помощью ffmpeg, чтобы разрешить запись видео в файл.

В Windows cvCreateVideoWriter() отобразит диалоговое окно для выбора соответствующего кодека, который вы хотите использовать при сохранении видео. Его можно изменить этот вызов функции, установив параметр, который будет жестко кодировать кодек ваших предпочтений.

Я написал это в спешке, но я знаю, что это работает.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <cv.h>
#include <highgui.h>
#include <cxtypes.h>
#include <cvaux.h>

int main()
{
    int camera_index = 0;
    IplImage *color_frame = NULL;
    int exit_key_press = 0;

    CvCapture *capture = NULL;
    capture = cvCaptureFromCAM(camera_index);
    if (!capture)
    {
        printf("!!! ERROR: cvCaptureFromCAM\n");
        return -1;
    }

    double cam_w = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
    double cam_h = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
    double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);    
    printf("* Capture properties: %f x %f - %f fps\n", cam_w, cam_h, fps); 

    cvNamedWindow("Grayscale video", CV_WINDOW_AUTOSIZE);

    CvVideoWriter* writer = NULL;
    writer = cvCreateVideoWriter("out.avi", -1, fps, cvSize((int)cam_w,(int)cam_h), 1);
    if (writer == NULL)
    {
        printf("!!! ERROR: cvCreateVideoWriter\n");
        return -1;
    }

    while (exit_key_press != 'q')
    {
        color_frame = cvQueryFrame(capture);
        if (color_frame == NULL)
        {
            printf("!!! ERROR: cvQueryFrame\n");
            break;
        }

        IplImage* gray_frame = cvCreateImage(cvSize(color_frame->width, color_frame->height), color_frame->depth, 1);  
        if (gray_frame == NULL)
        {
            printf("!!! ERROR: cvCreateImage\n");
            continue;
        }

        cvCvtColor(color_frame, gray_frame, CV_BGR2GRAY);
        cvShowImage("Grayscale video", gray_frame);

        cvWriteFrame(writer, gray_frame);

        cvReleaseImage(&gray_frame);

        exit_key_press = cvWaitKey(1);
    }

    cvReleaseVideoWriter(&writer);
    cvDestroyWindow("Grayscale video");
    cvReleaseCapture(&capture);

    return 0;
}

Ответ 3

Кажется, вы создаете видеофайл один раз для каждого кадра внутри цикла.

Создайте avi файл один раз в начале, затем добавьте каждый новый фрейм к нему с помощью cvWriteFrame()

Ответ 4

Потому что вы не выпустили изображение. это приведет к разрыву памяти. вам нужно выпустить изображение в вашем цикле.