Я пытаюсь записать видео с веб-камеры 1080p в файл. Я держал таймер в видео, и в каждом испытании метка времени, сообщаемая видеопроигрывателем (VLC — это то, что я использовал), не синхронизируется со временем в видео. Он всегда выключен на несколько секунд (обычно таймер в видео быстрее, чем время, указанное игроком).
Как показано ниже, я настроил программу C ++ для захвата видео в одном потоке и записи в другом потоке. Это работает нормально, так как мой процессор использует ~ 200% (возможно, макс?). Я использую MacBook Air с процессором Intel Core i7 10,8 с частотой 1,8 ГГц и частотой 10,8 ГГц.
Я попытался изменить частоту кадров до 15 кадров в секунду, и это приводит к очень прерывистому / медленному видео. Я также пытался установить CV_CAP_PROP_FRAME_WIDTH
& CV_CAP_PROP_FRAME_HEIGHT
к более низкому разрешению, и это приводит к медленному видео. Похоже, что 1080p при 30 кадрах в секунду дает хорошее устойчивое видео, но оно все равно всегда воспроизводится быстрее, чем предполагалось. Я также пытался положить в waitKey(10);
после record << frame;
но это ни на что не повлияло.
Любые рекомендации о том, как сделать так, чтобы видео совпадало по времени?
Спасибо!
Aakash
#include "opencv/cv.h"#include "opencv/highgui.h"#include <boost/thread.hpp>
using namespace cv;
void captureFunc(Mat *frame, VideoCapture *capture){
for(;;){
// get a new frame from camera
(*capture) >> (*frame);
}
}
int main(int, char**)
{
VideoCapture capture(0); // open the default camera
if( !capture.isOpened() ) {
printf("Camera failed to open!\n");
return -1;
}
capture.set(CV_CAP_PROP_FPS,30); //set capture rate to 30fps
Mat frame;
capture >> frame; // get first frame for size
// initialize recording of video
VideoWriter record("test.avi", CV_FOURCC('D','I','V','X'), 30, frame.size(), true);
if( !record.isOpened() ) {
printf("VideoWriter failed to open!\n");
return -1;
}
boost::thread captureThread(captureFunc, &frame, &capture); //start capture thread
sleep(1); //just to make sure capture thread is ready
for(;;)
{
// add frame to recorded video
record << frame;
}
return 0;
}
Я решил свою проблему после небольшой отладки; проблема была в том, что VideoWriter требователен к скорости передачи кадров.
Вам нужно синхронизировать ваши функции чтения и записи. Ваш код читает как можно быстрее, а пишет также максимально быстро. Ваше выходное видео, вероятно, выглядит медленным, потому что запись вывода происходит быстрее, чем чтение ввода (так как capture >>
ждет вашей камеры), и несколько идентичных кадров записываются.
Запись без ожидания или синхронизации означает, что вы можете написать один и тот же контент несколько раз (что, я думаю, здесь происходит) или потерять фреймы.
Если вы хотите продолжать иметь потоки, вы можете, но вам нужно будет заставить процесс записи ждать, пока что-то не получится новый написать.
Аналогично, чтобы избежать потери кадров или записи поврежденных кадров, вам нужно, чтобы процесс чтения ожидал завершения записи, так что frame
может быть безопасно перезаписано.
Так как потоки все равно должны ждать друг друга, в потоках вообще мало смысла.
Я бы порекомендовал этот гораздо более простой способ:
for (;;) {
capture >> frame;
process(frame); // whatever smart you need
record << frame;
}
Если вам нужен параллелизм, вам понадобится гораздо более сложный механизм синхронизации и, возможно, какой-то тип fifo для ваших кадров.