![](/img/trans.png)
[英]unable to write the output video in OpenCV, program is writing only single frame
[英]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.