簡體   English   中英

使用openCV編寫視頻 - 沒有為曲目0設置關鍵幀

[英]Writing video with openCV - no key frame set for track 0

我正在嘗試使用以下代碼使用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);

當我嘗試用VLC運行輸出視頻'test.avi'時,我得到以下錯誤:avidemux錯誤:沒有為磁道0設置關鍵幀。我正在使用Ubuntu 13.04,我嘗試使用MPEG編碼的視頻4和libx264。 我認為修復應該是直截了當的,但找不到任何指導。 實際代碼可在https://github.com/benselby/robot_nav/tree/master/video_unwrap上找到 提前致謝!

[PYTHON]除了分辨率不匹配外,還可能存在每秒幀數不匹配的情況。 就我而言,分辨率設置正確,但問題出在fps上。 檢查VideoCapture對象正在讀取的每秒幀數,它顯示為30.0,但如果我將VideoWriter對象的fps設置為30.0,則在VLC中拋出相同的錯誤。 您可以通過將其設置為30來解決錯誤,而不是將其設置為30.0。

PS您可以使用cap.get(3)表示寬度, cap.get(4)表示高度, cap.get(5)表示捕獲while / for循環內的fps,可以檢查分辨率和錄制的fps 。

完整代碼如下:

import numpy as np
import cv2 as cv2
cap = cv2.VideoCapture(0)

#Define Codec and create a VideoWriter Object
fourcc = cv2.VideoWriter_fourcc('X','V','I','D')
#30.0 in the below line doesn't work while 30 does work.
out = cv2.VideoWriter('output.mp4', fourcc, 30, (640, 480))

while(True):
    ret, frame = cap.read()
    colored_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2BGRA)
    print('Width = ', cap.get(3),' Height = ', cap.get(4),' fps = ', cap.get(5))
    out.write(colored_frame)
    cv2.imshow('frame', colored_frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
out.release()
cv2.destroyAllWindows()

有關所有屬性可以檢查的完整文檔(C ++),請參見: propId OpenCV文檔

這似乎是所寫幀和打開的VideoWriter對象之間大小不匹配的問題。 當我嘗試將一系列經過調整的圖像從我的網絡攝像頭寫入視頻輸出時,我遇到了這個問題。 當我刪除調整大小步驟並從初始測試框架中抓取尺寸時,一切都完美無缺。

為了修復我的調整大小代碼,我基本上通過我的處理運行了一個測試框架,然后在創建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 );

我不確定你的幀來自哪里(即如何設置捕獲),但可能在舍入或其他地方你的大小搞砸了。 我建議做一些類似於我上面的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM