环境:win10+opencv4.5.3+opencv_contrib-4.5.3+vs2019
状态:禁用笔记本自带摄像头,使用webcam
问题
配置好opencv和contrib库后,通过opencv打开webcam,发现无论debug还是release编译起图非常慢,而且有一些fail的提示。
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(int, char**)
{
int cameraIndex = 0;
// 实例化
VideoCapture camera;
camera.open(cameraIndex); // 打开摄像头, 默认摄像头cameraIndex=0
if (!camera.isOpened())
{
cerr << "Couldn't open camera." << endl;
}
// 循环读取视频帧
while (true)
{
cv::Mat frame;
camera >> frame;
cv::imshow("camera", frame);
if (cv::waitKey(33) == 27) break; // ESC 键退出
}
// 释放
camera.release();
cv::destroyWindow("camera");
return 0;
}
debug运行后出现如下提示:
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\videoio\src\videoio_registry.cpp (217) cv::`anonymous-namespace'::VideoB
ackendRegistry::VideoBackendRegistry VIDEOIO: Enabled backends(8, sorted by priority): FFMPEG(1000); GSTREAMER(990); INT
EL_MFX(980); MSMF(970); DSHOW(960); CV_IMAGES(950); CV_MJPEG(940); UEYE(930)
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\videoio\src\backend_plugin.cpp (380) cv::impl::getPluginCandidates Found
2 plugin(s) for GSTREAMER
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\core\src\utils\plugin_loader.impl.hpp (67) cv::plugin::impl::DynamicLib:
:libraryLoad load C:\opencv\build\install\x64\vc16\bin\opencv_videoio_gstreamer453_64d.dll => FAILED
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\core\src\utils\plugin_loader.impl.hpp (67) cv::plugin::impl::DynamicLib:
:libraryLoad load opencv_videoio_gstreamer453_64d.dll => FAILED
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\videoio\src\cap_msmf.cpp (788) CvCapture_MSMF::configureHW MSMF: Using D
3D11 video acceleration on GPU device: Intel(R) Iris(R) Xe Graphics
然后会卡在这里等将近1分钟时间才能开启摄像头,之后出现n多信息:
...
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\core\src\parallel\registry_parallel.impl.hpp (96) cv::parallel::Parallel
BackendRegistry::ParallelBackendRegistry core(parallel): Enabled backends(3, sorted by priority): ONETBB(1000); TBB(990)
; OPENMP(980)
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\core\src\utils\plugin_loader.impl.hpp (67) cv::plugin::impl::DynamicLib:
:libraryLoad load C:\opencv\build\install\x64\vc16\bin\opencv_core_parallel_onetbb453_64d.dll => FAILED
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\core\src\utils\plugin_loader.impl.hpp (67) cv::plugin::impl::DynamicLib:
:libraryLoad load opencv_core_parallel_onetbb453_64d.dll => FAILED
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\core\src\utils\plugin_loader.impl.hpp (67) cv::plugin::impl::DynamicLib:
:libraryLoad load C:\opencv\build\install\x64\vc16\bin\opencv_core_parallel_tbb453_64d.dll => FAILED
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\core\src\utils\plugin_loader.impl.hpp (67) cv::plugin::impl::DynamicLib:
:libraryLoad load opencv_core_parallel_tbb453_64d.dll => FAILED
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\core\src\utils\plugin_loader.impl.hpp (67) cv::plugin::impl::DynamicLib:
:libraryLoad load C:\opencv\build\install\x64\vc16\bin\opencv_core_parallel_openmp453_64d.dll => FAILED
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\core\src\utils\plugin_loader.impl.hpp (67) cv::plugin::impl::DynamicLib:
:libraryLoad load opencv_core_parallel_openmp453_64d.dll => FAILED
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\highgui\src\registry.impl.hpp (114) cv::highgui_backend::UIBackendRegist
ry::UIBackendRegistry UI: Enabled backends(4, sorted by priority): GTK(1000); GTK3(990); GTK2(980); WIN32(970) + BUILTIN
(WIN32UI)
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\core\src\utils\plugin_loader.impl.hpp (67) cv::plugin::impl::DynamicLib:
:libraryLoad load C:\opencv\build\install\x64\vc16\bin\opencv_highgui_gtk453_64.dll => FAILED
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\core\src\utils\plugin_loader.impl.hpp (67) cv::plugin::impl::DynamicLib:
:libraryLoad load opencv_highgui_gtk453_64.dll => FAILED
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\core\src\utils\plugin_loader.impl.hpp (67) cv::plugin::impl::DynamicLib:
:libraryLoad load C:\opencv\build\install\x64\vc16\bin\opencv_highgui_gtk3453_64.dll => FAILED
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\core\src\utils\plugin_loader.impl.hpp (67) cv::plugin::impl::DynamicLib:
:libraryLoad load opencv_highgui_gtk3453_64.dll => FAILED
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\core\src\utils\plugin_loader.impl.hpp (67) cv::plugin::impl::DynamicLib:
:libraryLoad load C:\opencv\build\install\x64\vc16\bin\opencv_highgui_gtk2453_64.dll => FAILED
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\core\src\utils\plugin_loader.impl.hpp (67) cv::plugin::impl::DynamicLib:
:libraryLoad load opencv_highgui_gtk2453_64.dll => FAILED
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\highgui\src\backend.cpp (90) cv::highgui_backend::createUIBackend UI: us
ing backend: WIN32 (priority=970)
[ INFO:0] global C:\opencv\opencv-4.5.3\modules\highgui\src\window_w32.cpp (3009) cv::impl::Win32BackendUI::createWindow
OpenCV/UI: Creating Win32UI window: camera (1)
使用release编译也是一样的问题,只不过release在窗口不显示INFO提示。
分析
- 既然可以起图,那应该是期间启用后端I/O接口的时候,造成了延误或者中断。通过查看debug的日志,可以看到好多FAILED的项目。
VIDEOIO: Enabled backends(8, sorted by priority): FFMPEG(1000)
load opencv_videoio_gstreamer453_64d.dll => FAILED
load opencv_core_parallel_onetbb453_64d.dll => FAILED
load opencv_core_parallel_tbb453_64d.dll => FAILED
load opencv_core_parallel_openmp453_64d.dll => FAILED
load opencv_highgui_gtk453_64.dll => FAILED
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。
GStreamer 是用来构建流媒体应用的开源多媒体框架(framework),其目标是要简化音/视频应用程序的开发,已经能够被用来处理像 MP3、Ogg、MPEG1、MPEG2、AVI、Quicktime 等多种格式的多媒体数据。
oneAPI Threading Building Blocks,原名Threading Building Blocks,是英特尔开发的用于多核处理器上并行编程的C++模板库。 使用 TBB,计算被分解为可以并行运行的任务。 库管理和调度线程来执行这些任务。
OpenMP是由OpenMP Architecture Review Board牵头提出的,并已被广泛接受,用于共享内存并行系统的多处理器程序设计的一套指导性编译处理方案(Compiler Directive) 。
GTK+(GIMP Toolkit)是一套源码以LGPL许可协议分发、跨平台的图形工具包。最初是为GIMP写的,已成为一个功能强大、设计灵活的一个通用图形库,是GNU/Linux下开发图形界面的应用程序的主流开发工具之一。
最后使用的是:
UI: using backend: WIN32 (priority=970)
看起来好像就是打开webcam时,在找一个合适的接口的时候,浪费了时间,比较慢。
opencv video i/o 的介绍:
opencv有许多I/O API,详见:cv::VideoCaptureAPIs
VideoCapture camera;
camera.open(cameraIndex); // 打开摄像头, 默认摄像头cameraIndex=0,默认后端CAP_ANY
如果在开始的时候,不指定API,OpenCV 会自动选择并使用第一个可用的后端 ( )。apiPreference=cv::CAP_ANY,猜测自动选取的过程造成了延迟。
解决
我们可以选择要在运行时使用的后端。例如,使用 Direct Show 作为后端从默认相机中抓取。
//declare a capture object
cv::VideoCapture cap(0, cv::CAP_DSHOW);
//or specify the apiPreference with open
cap.open(0, cv::CAP_DSHOW);
这样起图就快了。