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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 01:49:00  来源:igfitidea点击:

Fastest way to grab frames from video file OpenCV

objective-cxcodevideoopencvframes

提问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 waitKeyas 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_ONmacro: ~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 setmethodto 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

这将缩短您处理每一帧所需的时间,因为它们会更小。希望能帮助到你