xcode 从视频文件 OpenCV 中抓取帧的最快方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12876113/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fastest way to grab frames from video file OpenCV
提问by kava
I want to do some openCV Video processing. Im on a Mac working with openCV in Xcode 4 so in fact my code is Objective C++.
我想做一些 openCV 视频处理。我在 Mac 上使用 Xcode 4 中的 openCV,所以实际上我的代码是 Objective C++。
I want to access all frames of a video as fast as possible (without displaying it and without drops) and do calculations on them.
我想尽快访问视频的所有帧(不显示也不丢失)并对它们进行计算。
my code to get the frames:
我获取帧的代码:
CvCapture* capture = cvCaptureFromFile("A MOVIE FILE HERE");
IplImage* frame;
while(1) {
frame = cvQueryFrame(capture);
if (!frame) break;
// openCV Stuff here...
char c = cvWaitKey(1);
if(c==27) break;
}
I know the speed massively depends on Codec/Resolution/Bitrate - but it seems that I can't read with more than 120% speed... any idea how to grab frames faster?
我知道速度在很大程度上取决于编解码器/分辨率/比特率 - 但似乎我无法以超过 120% 的速度阅读......知道如何更快地抓取帧吗?
回答by ArtemStorozhuk
Actually there's only one thing that slows your program - it's waitKey
as Quentin Geissmannalready mentioned. And if you say:
实际上,只有一件事会减慢您的程序速度 -waitKey
正如Quentin Geissmann已经提到的那样。如果你说:
tried that already - forgot to mention that. Didn't really speed up things.
已经试过了 - 忘记提及了。并没有真正加快速度。
Than I don't believe you because I have just tested it on my environment and it speeds up on 30-40%.
我不相信你,因为我刚刚在我的环境中对其进行了测试,它的速度提高了 30-40%。
Here's benchmark code:
这是基准代码:
#define WAIT_ON
int main()
{
cv::Mat frame;
cv::VideoCapture capture = cv::VideoCapture("video/in.avi");
int k;
double benchTime = (double)cv::getTickCount();
while (1)
{
capture >> frame;
if (!frame.data)
{
break;
}
#ifdef WAIT_ON
k = cv::waitKey(1);
if (k == 27)
{
break;
}
#endif
}
std::cout << ((double)cv::getTickCount() - benchTime)/cv::getTickFrequency() << std::endl;
}
Video input: 854x480, 24fps, 2:00
.
视频输入:854x480, 24fps, 2:00
.
With WAIT_ON
macro: ~11 sec
使用WAIT_ON
宏:~11 秒
Without: ~7.3 sec
没有:~7.3 秒
Update:
更新:
To reduce image resolution in videostream set these parameters:
要降低视频流中的图像分辨率,请设置以下参数:
CV_CAP_PROP_FRAME_WIDTH Width of the frames in the video stream.
CV_CAP_PROP_FRAME_HEIGHT Height of the frames in the video stream.
in set
methodto other (320x240).
inset
方法到其他 (320x240)。
回答by Quentin Geissmann
I have noticed several times that cv::waitKey()
/cvWaitKey()
is not accurate for short (<10ms) times. In fact, in my case, it seems to sleep for at least 10ms with any values under 10ms. Maybe someone can bring more precision about this, but I would suggest to remove itfrom your loop (if you can).
我多次注意到cv::waitKey()
/cvWaitKey()
在短时间内(<10ms)不准确。事实上,就我而言,它似乎至少休眠 10 毫秒,任何值都低于 10 毫秒。也许有人可以对此进行更精确的处理,但我建议将其从循环中删除(如果可以的话)。
I hope it works, Good luck
我希望它有效,祝你好运
回答by CAta.RAy
The functions
功能
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 320);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 200);
do not affect the video itself, if you like to change the resolution of the frames, you can use something like:
不要影响视频本身,如果你想改变帧的分辨率,你可以使用类似的东西:
cv::Size videoSize = cv::Size ((int) 320, (int) 200);
cv::resize(srcFrame,resFrame, videoSize);
This will improve the time you need to process each frame since they will be smaller. Hope it helps
这将缩短您处理每一帧所需的时间,因为它们会更小。希望能帮助到你