OpenCV4 | 如何让传统图像处理实现三十倍加速的顶级技能

点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

OpenCV4 + CUDA 从配置到代码.....

引子

一直有人在研习社问我,怎么去做OpenCV + CUDA的加速支持。其实网上用搜索引擎就可以找到一堆文章,但是其实你会发现,按照他们的做法基本都不会成功,原因是因为文章中使用的OpenCV版本太老旧、英伟达GPU的CUDA库也太久远。其实这个都不是主要原因,真实原因是OpenCV4跟之前的版本,编译CUDA的方法不一样了。所以感觉有必要自己写一遍,作为全网第一个OpenCV4 + CUDA + GPU编译与代码测试的教程给大家。希望大家都可以获得此技能,整个教程分为如下几个部分:

1. CUDA软件安装与配置

2. OpenCV+cmake编译CUDA模块支持

3. 代码实现与测试

4. 模块支持与应用场景

在开始教程之前,先说一下相关软件与版本信息

Windows 10 64bit

英伟达CUDA 10.0

OpenCV 4.1.0

OpenCV扩展模块4.1.0

GTX 1050 TI

VS2015 专业版

CMake 3.13.4

CUDA软件安装与配置

01

首先确保你有英伟达的独立显卡(GPU),然后请到英伟达官方网站,在线检查与下载最新的显卡驱动版本。地址如下:

https://www.geforce.cn/drivers

安装/更新好驱动之后,就可以下载对应版本的CUDA工具包,下载地址如下:

https://developer.nvidia.com/cuda-toolkit
https://developer.nvidia.com/rdp/cudnn-download

下载好之后,就可以开始进行安装,只要默认安装即可。关于CUDA的安装与配置,更加详细的内容可以参考这里:

上面的文章中已经详细交代了。安装好之后我们就完成了第一步操作。

OpenCV+CMake编译

02

首先安装好CMake,下载地址如下:

www.cmake.org

其次需要下载OpenCV与OpenCV扩展模块的源代码,地址如下:

https://github.com/opencv/opencv/releases/download/4.1.0/opencv-4.1.0-vc14_vc15.exe
https://github.com/opencv/opencv_contrib/archive/4.1.0.zip

下载好之后解压缩到D盘指定目录即可。

打开CMake,设置好源码路径与编译输出路径之后,显示如下:

66b2f9db8765bfa3d71bc82d16b36850.png

点击【configure】目标,弹出对话框选择如下:

f1074acecd6f38dce24302a9f0472801.png

然后点击【Finish】完成config之后,再点击【generate】按钮。

编译CUDA与扩展模块

完成上述操作之后,然后找到OPENCV_EXTRA_MODULE_PATH设置扩展模块的源代码路径。设置以后,在搜索框中输入CUDA,

WITH_CUDA
BUILD_CUDA_STUBS

上述两个选项打勾之后,再次点击【configure】按钮,完成之后,显示如下:

5c6884462df804a02f7ebcb8db528e62.png

CUDA_FAST_MATH选项打勾,然后执行【Generate】按钮。最终CMake的结果如下:

e6002769de6f4b54e4d11aa8751d5974.png

这个时候去cudabuild这里目录下,双击打开OpenCV.sln(VS2015工程文件),选择CMake_Targets -> ALL_BUILD,然后右键->生成,完成之后,再选择INSTALL右键生成。这个过程时间会比较久一点,估计会有一个小时到两个小时左右,跟电脑性能有关系。完成之后,你就会看到再cudabuild目录下多出一个install目录,这个就是我们编译得到支持CUDA版本的OpenCV。打开检查一下:

a041c33473089c5a443fb6fe31411d3c.png

我的是今天早晨刚刚完成编译的。然后按照正常的OpenCV配置,配置好VS2015+OpenCV开发环境。如果还不知道怎么配置,看这里:

https://www.bilibili.com/video/av36486959

这里需要特别注意一点,我这里没有勾选生成opencv_world,主要是怕编译过程中有模块出错,会导致生产失败,所以就每个模块生成一个lib/dll的库。配置的lib链接器的时候,需要把下面的库文件全部加入:

opencv_aruco410d.lib

opencv_bgsegm410d.lib

opencv_bioinspired410d.lib

opencv_calib3d410d.lib

opencv_ccalib410d.lib

opencv_core410d.lib

opencv_cudaarithm410d.lib

opencv_cudabgsegm410d.lib

opencv_cudacodec410d.lib

opencv_cudafeatures2d410d.lib

opencv_cudafilters410d.lib

opencv_cudaimgproc410d.lib

opencv_cudalegacy410d.lib

opencv_cudaobjdetect410d.lib

opencv_cudaoptflow410d.lib

opencv_cudastereo410d.lib

opencv_cudawarping410d.lib

opencv_cudev410d.lib

opencv_datasets410d.lib

opencv_dnn410d.lib

opencv_dnn_objdetect410d.lib

opencv_dpm410d.lib

opencv_face410d.lib

opencv_features2d410d.lib

opencv_flann410d.lib

opencv_fuzzy410d.lib

opencv_gapi410d.lib

opencv_hfs410d.lib

opencv_highgui410d.lib

opencv_imgcodecs410d.lib

opencv_imgproc410d.lib

opencv_img_hash410d.lib

opencv_line_descriptor410d.lib

opencv_ml410d.lib

opencv_objdetect410d.lib

opencv_optflow410d.lib

opencv_phase_unwrapping410d.lib

opencv_photo410d.lib

opencv_plot410d.lib

opencv_quality410d.lib

opencv_reg410d.lib

opencv_rgbd410d.lib

opencv_saliency410d.lib

opencv_shape410d.lib

opencv_stereo410d.lib

opencv_stitching410d.lib

opencv_structured_light410d.lib

opencv_superres410d.lib

opencv_surface_matching410d.lib

opencv_text410d.lib

opencv_tracking410d.lib

opencv_video410d.lib

opencv_videoio410d.lib

opencv_videostab410d.lib

opencv_xfeatures2d410d.lib

opencv_ximgproc410d.lib

opencv_xobjdetect410d.lib

opencv_xphoto410d.lib

 特别提醒,千万不要copy我的,因为也许你的版本不是OpenCV4.1.0,或者你的编译生成有模块失败,没有我这么多lib文件。这样我们就完成了CUDA编译支持。这里需要特别注意的,在VS2015编译阶段,必须先选择ALL_BUILD,切记

OpenCV代码测试与运行

03

OpenCV4支持CUDA运行的模块,主要包括 图像处理、视频读写、视频分析、传统的对象检测包括HOG、级联检测器、特征提取部分、卷积滤波与图像二值分析、图像分割模块。这里我在OpenCV提供的示例代码基础上稍加改动,实现了一个基于背景分割的视频分析程序:

#include <iostream>
#include <string>

#include "opencv2/core.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/cudabgsegm.hpp"
#include "opencv2/video.hpp"
#include "opencv2/highgui.hpp"

using namespace std;
using namespace cv;
using namespace cv::cuda;

enum Method
{
    MOG,
    MOG2,
};

int main(int argc, const char** argv)
{
    Method m = MOG;

    int count = cuda::getCudaEnabledDeviceCount();
    printf("GPU Device Count : %d \n", count);

    VideoCapture cap;
    cap.open("D:/images/video/example_dsh.mp4");

    Mat frame;
    cap >> frame;

    GpuMat d_frame(frame);

    Ptr<BackgroundSubtractor> mog = cuda::createBackgroundSubtractorMOG();
    Ptr<BackgroundSubtractor> mog2 = cuda::createBackgroundSubtractorMOG2();

    GpuMat d_fgmask;
    GpuMat d_fgimg;
    GpuMat d_bgimg;

    Mat fgmask;
    Mat fgimg;
    Mat bgimg;

    switch (m)
    {
    case MOG:
        mog->apply(d_frame, d_fgmask, 0.01);
        break;

    case MOG2:
        mog2->apply(d_frame, d_fgmask);
        break;
    }

    namedWindow("image", WINDOW_AUTOSIZE);
    namedWindow("foreground mask", WINDOW_AUTOSIZE);
    namedWindow("foreground image", WINDOW_AUTOSIZE);
    namedWindow("mean background image", WINDOW_AUTOSIZE);

    for (;;)
    {
        cap >> frame;
        if (frame.empty())
            break;
        int64 start = cv::getTickCount();
        d_frame.upload(frame);


        //update the model
        switch (m)
        {
        case MOG:
            mog->apply(d_frame, d_fgmask, 0.01);
            mog->getBackgroundImage(d_bgimg);
            break;

        case MOG2:
            mog2->apply(d_frame, d_fgmask);
            mog2->getBackgroundImage(d_bgimg);
            break;
        }


        d_fgimg.create(d_frame.size(), d_frame.type());
        d_fgimg.setTo(Scalar::all(0));
        d_frame.copyTo(d_fgimg, d_fgmask);

        d_fgmask.download(fgmask);
        d_fgimg.download(fgimg);
        if (!d_bgimg.empty())
            d_bgimg.download(bgimg);

        imshow("foreground mask", fgmask);
        imshow("foreground image", fgimg);
        if (!bgimg.empty())
            imshow("mean background image", bgimg);

        double fps = cv::getTickFrequency() / (cv::getTickCount() - start);
        // std::cout << "FPS : " << fps << std::endl;
        putText(frame, format("FPS : %.2f", fps), Point(50, 50), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 255), 2, 8);

        imshow("image", frame);
        char key = (char)waitKey(1);
        if (key == 27)
            break;
    }

    return 0;
}

在我的电脑上 基于1080P的视频文件

  • CPU版本的运行是大概在2FPS

  • GPU版本CUDA加速运行大概在 80 FPS

337a9997b89e1813b702b843f87f6bed.png

怎么说,完全是碾压式的速度优势。看来以后视频处理必须CUDA版本才过瘾。来自官方的更多加速比较图示如下:

86b7599b93b32be645e1ef44ad2eba33.png

测试1920x1080大小的视频文件,处理帧率如下:

f94d95d88b0c9a0d62a64d33d23a35cb.png

可以说完全实时无压力!

模块支持与应用场景

04

既然CUDA加速这么厉害,为什么OpenCV在正式的release中却没有包含呢?本人觉得OpenCV正式的官方Release版本主要是考虑普适性的问题。另外OpenCV在3.x到4.x升级的时候把CUDA支持从release移到扩展模块中去了,官方也没有解释为什么,我个人感觉更多的是出于商业考虑。

此外OpenCV中DNN模块已经支持OpenVINO加速执行与NCS2加速、所以OpenCV DNN模块不支持英伟达显卡加速支持,支持的模块大部分是以前的传统图像处理、对象检测、特征匹配、双目、图像拼接部分,其实这些对我们已经十分有用,大大扩展了OpenCV的应用场景、另外千万不要随便使用CUDA加速,有些简单的算法,OpenCV已经做的很好了,加速的效果并不明显,不信可以看下面的这个例子:

39726896b92aac8ef3ae892238e90be5.png

有点是车祸现场,原因很好解释。这个是因为OpenCV中使用CUDA需要把Mat对象数据上传到CUDA支持单元,完成处理以后再下载到Mat对象上,对一些简单的图像处理,这个操作很容易成为性能瓶颈,从而降低了加速效应。

 
 
小白团队出品:零基础精通语义分割↓↓↓

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程,即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。


下载2:Python视觉实战项目52讲
在「小白学视觉」公众号后台回复:Python视觉实战项目,即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。


下载3:OpenCV实战项目20讲
在「小白学视觉」公众号后台回复:OpenCV实战项目20讲,即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。


交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV(Open Source Computer Vision Library)是一款开源的计算机视觉库,专门为图像和视频处理任务设计,广泛应用于学术研究、工业应用以及个人项目中。以下是关于OpenCV的详细介绍: 历史与发展 起源:OpenCV于1999年由英特尔公司发起,旨在促进计算机视觉技术的普及和商业化应用。该项目旨在创建一个易于使用、高效且跨平台的库,为开发者提供实现计算机视觉算法所需的基础工具。 社区与支持:随着时间的推移,OpenCV吸引了全球众多开发者和研究人员的参与,形成了活跃的社区。目前,OpenCV由非盈利组织OpenCV.org维护,并得到了全球开发者、研究机构以及企业的持续贡献和支持。 主要特点 跨平台:OpenCV支持多种操作系统,包括但不限于Windows、Linux、macOS、Android和iOS,确保代码能够在不同平台上无缝运行。 丰富的功能:库中包含了数千个优化过的函数,涵盖了计算机视觉领域的诸多方面,如图像处理(滤波、形态学操作、色彩空间转换等)、特征检测与描述(如SIFT、SURF、ORB等)、物体识别与检测(如Haar级联分类器、HOG、DNN等)、视频分析、相机校正、立体视觉、机器学习(SVM、KNN、决策树等)、深度学习(基于TensorFlow、PyTorch后端的模型加载与部署)等。 高效性能:OpenCV代码经过高度优化,能够利用多核CPU、GPU以及特定硬件加速(如Intel IPP、OpenCL等),实现高速图像处理和实时计算机视觉应用。 多语言支持:尽管OpenCV主要使用C++编写,但它提供了丰富的API绑定,支持包括C、PythonJava、MATLAB、JavaScript等多种编程语言,方便不同领域的开发者使用。 开源与免费:OpenCV遵循BSD开源许可证发布,用户可以免费下载、使用、修改和分发库及其源代码,无需担心版权问题。 架构与核心模块 OpenCV的架构围绕核心模块构建,这些模块提供了不同层次的功能: Core:包含基本的数据结构(如cv::Mat用于图像存储和操作)、基本的图像和矩阵操作、数学函数、文件I/O等底层功能。 ImgProc:提供图像预处理、滤波、几何变换、形态学操作、直方图计算、轮廓发现与分析等图像处理功能。 HighGui:提供图形用户界面(GUI)支持,如图像和视频的显示、用户交互(如鼠标事件处理)以及简单的窗口管理。 VideoIO:负责视频的读写操作,支持多种视频格式和捕获设备。 Objdetect:包含预训练的对象检测模型(如Haar级联分类器用于人脸检测)。 Features2D:提供特征点检测(如SIFT、ORB)与描述符计算、特征匹配与对应关系估计等功能。 Calib3d:用于相机标定、立体视觉、多视图几何等问题。 ML:包含传统机器学习算法,如支持向量机(SVM)、K近邻(KNN)、决策树等。 DNN:深度神经网络模块,支持导入和运行预训练的深度学习模型,如卷积神经网络(CNN)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值