5

次のコードを使用して、openCV 2.4.6.1 を使用していくつかのビデオを変更して書き込もうとしています。

cv::VideoCapture capture( video_filename );

    // Check if the capture object successfully initialized
    if ( !capture.isOpened() ) 
    {
        printf( "Failed to load video, exiting.\n" );
        return -1;
    }

    cv::Mat frame, cropped_img;

    cv::Rect ROI( OFFSET_X, OFFSET_Y, WIDTH, HEIGHT );


    int fourcc = static_cast<int>(capture.get(CV_CAP_PROP_FOURCC));
    double fps = 30;
    cv::Size frame_size( RADIUS, (int) 2*PI*RADIUS );
    video_filename = "test.avi";
    cv::VideoWriter writer( video_filename, fourcc, fps, frame_size );

    if ( !writer.isOpened() && save )
    {
        printf("Failed to initialize video writer, unable to save video!\n");
    }

    while(true)
    {   
        if ( !capture.read(frame) )
        {
            printf("Failed to read next frame, exiting.\n");
            break;
        }

        // select the region of interest in the frame
        cropped_img = frame( ROI );                 

        // display the image and wait
        imshow("cropped", cropped_img);

        // if we are saving video, write the unwrapped image
        if (save)
        {
            writer.write( cropped_img );
        }

        char key = cv::waitKey(30);

出力ビデオ 'test.avi' を VLC で実行しようとすると、次のエラーが表示されます: avidemux エラー: トラック 0 にキー フレームが設定されていません。Ubuntu 13.04 を使用しており、MPEG でエンコードされたビデオを使用しようとしました4 と libx264。修正は簡単だと思いますが、ガイダンスが見つかりません。実際のコードはhttps://github.com/benselby/robot_nav/tree/master/video_unwrapで入手できます。前もって感謝します!

4

2 に答える 2

2

これは、書き込まれたフレームと開かれた VideoWriter オブジェクトの間のサイズの不一致の問題のようです。サイズを変更した一連の画像を Web カメラからビデオ出力に書き込もうとしたときに、この問題が発生していました。サイズ変更ステップを削除し、最初のテスト フレームからサイズを取得したところ、すべてが完全に機能しました。

サイズ変更コードを修正するために、基本的に、処理を通じて 1 つのテスト フレームを実行し、VideoWriter オブジェクトの作成時にそのサイズを取得しました。

#include <cassert>
#include <iostream>
#include <time.h>

#include "opencv2/opencv.hpp"

using namespace cv;

int main()
{
    VideoCapture cap(0);
    assert(cap.isOpened());

    Mat testFrame;
    cap >> testFrame;
    Mat testDown;
    resize(testFrame, testDown, Size(), 0.5, 0.5, INTER_NEAREST);
    bool ret = imwrite("test.png", testDown);
    assert(ret);

    Size outSize = Size(testDown.cols, testDown.rows);
    VideoWriter outVid("test.avi", CV_FOURCC('M','P','4','2'),1,outSize,true);
    assert(outVid.isOpened());

    for (int i = 0; i < 10; ++i) {
        Mat frame;
        cap >> frame;

        std::cout << "Grabbed frame" << std::endl;

        Mat down;
        resize(frame, down, Size(), 0.5, 0.5, INTER_NEAREST);

        //bool ret = imwrite("test.png", down);
        //assert(ret);
        outVid << down;


        std::cout << "Wrote frame" << std::endl;
        struct timespec tim, tim2;
        tim.tv_sec = 1;
        tim.tv_nsec = 0;
        nanosleep(&tim, &tim2);
    }
}

私の推測では、あなたの問題はサイズの計算にあります:

cv::Size frame_size( RADIUS, (int) 2*PI*RADIUS );

フレームがどこから来ているのか (つまり、キャプチャがどのように設定されているのか) はわかりませんが、丸めや他の場所でサイズが台無しになる可能性があります。上記のソリューションと同様のことを行うことをお勧めします。

于 2014-11-14T03:19:58.883 に答える