我最近开始使用OpenCV。虽然一开始我取得了很多进展,但是现在我快要因为看起来很简单的任务而失去理智:使用Raspberry Pi相机记录一个简单的视频。问题在于生成的视频似乎是快进的,并且原因似乎是在录制时没有写入所需帧的一半。
经过许多个小时的尝试编解码器和对我的代码进行时间测量以找到瓶颈,我现在发现问题似乎与OpenCV VideoCapture类有些相关,该类实例在我的代码中实际上提供的帧远少于预期。
所以我编写了一个简单的程序,在五秒钟内计算VideoCapture提供的帧数。将捕获属性设置为640x480x30fps可以正常工作,并提供约150个帧。但将其调整为1920x1080x30fps(根据规格是有效的相机模式并在其他应用程序中正常工作)最终只能在5秒内提供大约15个帧。
可能有非常明显的解决方案,但我完全无法想到。有人能帮帮我吗?谢谢!
经过许多个小时的尝试编解码器和对我的代码进行时间测量以找到瓶颈,我现在发现问题似乎与OpenCV VideoCapture类有些相关,该类实例在我的代码中实际上提供的帧远少于预期。
所以我编写了一个简单的程序,在五秒钟内计算VideoCapture提供的帧数。将捕获属性设置为640x480x30fps可以正常工作,并提供约150个帧。但将其调整为1920x1080x30fps(根据规格是有效的相机模式并在其他应用程序中正常工作)最终只能在5秒内提供大约15个帧。
可能有非常明显的解决方案,但我完全无法想到。有人能帮帮我吗?谢谢!
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <ctime>
float getElapsedCPUTime(std::clock_t begin){
return float(clock() - begin)/CLOCKS_PER_SEC;
}
std::time_t getCurrentWallTime(){
return std::time(nullptr);
}
int main (){
// int cols(640);
// int rows(480);
int cols(1920);
int rows(1080);
cv::Mat currentFrame;
// set capture properties
cv::VideoCapture cap(0);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, rows);
cap.set(CV_CAP_PROP_FRAME_WIDTH, cols);
cap.set(cv::CAP_PROP_FPS, 30);
cap.set(cv::CAP_PROP_FOURCC, 0x21);
// control capture properties
int rows_c(cap.get(CV_CAP_PROP_FRAME_HEIGHT));
int cols_c(cap.get(CV_CAP_PROP_FRAME_WIDTH));
int fps(cap.get(cv::CAP_PROP_FPS));
std::cout << "rows: " << rows_c << ", cols " << cols_c << ", fps " << fps << ", CPS: " << CLOCKS_PER_SEC << std::endl;
int cnt(0);
std::time_t loopExecution_begin(getCurrentWallTime());
while(1){
std::string msg("");
// capture frame
std::clock_t capture_begin(clock());
cap >> currentFrame;
float time_for_capture = getElapsedCPUTime(capture_begin);
++cnt;
// get elapsed wall time
std::time_t loopRunTime = getCurrentWallTime() - loopExecution_begin;
// output message
msg += "#: " + std::to_string(cnt);
msg += "\tTicks begin: " + std::to_string(capture_begin);
msg += "\tCapturetime: " + std::to_string(time_for_capture) + "s";
msg += "\tLoop Runtime: " + std::to_string(loopRunTime) + "s";
std::cout << msg << std::endl;
// break after 5s
if (loopRunTime > 5.0) break;
}
}
编辑:这是输出结果:
rows: 1080, cols 1920, fps 30, CPS: 1000000
#: 1 Ticks begin: 362378 Capturetime: 0.055826s Loop Runtime: 1s
#: 2 Ticks begin: 418543 Capturetime: 0.022631s Loop Runtime: 1s
#: 3 Ticks begin: 441338 Capturetime: 0.022695s Loop Runtime: 1s
#: 4 Ticks begin: 464196 Capturetime: 0.023302s Loop Runtime: 2s
#: 5 Ticks begin: 487659 Capturetime: 0.022729s Loop Runtime: 2s
#: 6 Ticks begin: 510551 Capturetime: 0.022631s Loop Runtime: 2s
#: 7 Ticks begin: 533349 Capturetime: 0.022663s Loop Runtime: 2s
#: 8 Ticks begin: 556176 Capturetime: 0.023194s Loop Runtime: 3s
#: 9 Ticks begin: 579535 Capturetime: 0.022640s Loop Runtime: 3s
#: 10 Ticks begin: 602337 Capturetime: 0.023267s Loop Runtime: 3s
#: 11 Ticks begin: 625789 Capturetime: 0.022741s Loop Runtime: 3s
#: 12 Ticks begin: 648694 Capturetime: 0.023210s Loop Runtime: 3s
#: 13 Ticks begin: 672069 Capturetime: 0.022487s Loop Runtime: 4s
#: 14 Ticks begin: 694721 Capturetime: 0.023162s Loop Runtime: 4s
#: 15 Ticks begin: 718051 Capturetime: 0.022611s Loop Runtime: 4s
#: 16 Ticks begin: 740822 Capturetime: 0.023602s Loop Runtime: 4s
#: 17 Ticks begin: 764600 Capturetime: 0.022555s Loop Runtime: 5s
#: 18 Ticks begin: 787321 Capturetime: 0.022532s Loop Runtime: 5s
#: 19 Ticks begin: 810019 Capturetime: 0.022626s Loop Runtime: 5s
#: 20 Ticks begin: 832813 Capturetime: 0.023161s Loop Runtime: 5s
#: 21 Ticks begin: 856138 Capturetime: 0.022543s Loop Runtime: 6s