Itseez 是俄罗斯的一家视觉公司,专门从事计算机视觉算法。2016 年 5 月,英特尔收购该公司,以“帮助英特尔的用户打造创新型深度学习的 CV 应用,如果自动驾驶、数字安全监控和工业检测”(英特尔物联网总经理 Doug Dacies 如此说)。
IPPICV 加速

给大家推荐一个国内OpenCV讲得最好的教程。
许多计算机科学家和经验丰富的程序员多多少少都了解计算机视觉的某些方面,但是很少有人熟谙计算机视觉的每一个应用。比如:
- 很多人了解计算机视觉在安保行业的应用;
- 一些人也知道它在网页端的图像和视频处理中的应用在逐渐增加。
DARPPA 机器人挑战赛(DRC)是机器人领域的一项重大赛事,堪称“机器人的奥林匹克”。
OpenCV 使用开源许可证
人类的视觉
计算机的视觉

一个数学物理定解问题的解如果存在,唯一并且稳定的,则说明该问题是适定的(well-posed);如果不满足,则说明该问题是不适定的(ill-posed)。
场景信息可以辅助计算机视觉
使用统计的方法来对抗噪声
Shinn Horng Lee (李信弘)是主要推动者,时任 IPP(集成性能基元)首席架构师。
- 为高级的视觉研究提供开源并且优化过的基础代码,不再需要重复造轮子。
- 以提供开发者可以在此基础上进行开发的通用接口为手段传播视觉相关知识,这样代码有更强的可读性和移植性。
- 以创造可移植的、优化过的免费开源代码来推动基于高级视觉的商业应用,这些代码可以自由使用,不要求商业应用程序开放或免费。
OpenCV 目前的情况

- 2016 年 12 月发布 OpenCV 3.2;
- 2017 年 8 月发布 OpenCV 3.3;
- 2017 年 12 月发布 OpenCV 3.4。
谁拥有OpenCV
OpenCV 是由很多模块组成的,这些模块可以分成很多层:
- 最底层是基于硬件加速层(HAL)的各种硬件优化。
- 再上一层是 opencv_contrib 模块所包含的 OpenCV 由其他开发人员所贡献的代码,其包含大多数高层级的函数功能。这就是OpenCV的核心。
- 接下来是语言绑定和示例应用程序。
- 处于最上层的是 OpenCV 和操作系统的交互。

| 模块 | 说明 |
|---|---|
| Core | 该模块包含 OpenCV 库的基础结构以及基本操作。 |
| Improc | 图像处理模块包含基本的图像转换,包括滤波以及类似的卷积操作。 |
| Highgui | 在 OpenCV 3.0中,分割为 imcodecs、videoio 以及 highgui 三部分。
这个模块包含可以用来显示图像或者简单的输入的用户交互函数。这可以看作是一个非常轻量级的 Windows UI 工具包。 |
| Video | 该模块包含读取和写视频流的函数。 |
| Calib3d | 这个模块包括校准单个、双目以及多个相机的算法实现。 |
| Feature2d | 这个模块包含用于检测、描述以及匹配特征点的算法。 |
| Objdectect | 这个模块包含检测特定目标,比如人脸或者行人的算法。也可以训练检测器并用来检测其他物体。 |
| Ml | 机器学习模块本身是一个非常完备的模块,包含大量的机器学习算法实现并且这些算法都能和 OpenCV 的数据类型自然交互。 |
| Flann | Flann 的意思是“快速最邻近库”。这个库包含一些你也许不会直接使用的方法,但是其他模块中的函数会调用它在数据集中进行最邻近搜索。 |
| GPU | 在 OpenCV 中被分割为多个 cuda* 模块。
GPU 模块主要是函数在 CUDA GPU 上的优化实现,此外,还有一些仅用于 GPU 的功 能。其中一些函数能够返回很好的结果,但是需要足够好的计算资源,如果硬件没有GPU,则不会有什么提升。 |
| Photo | 这是一个相当新的模块,包含计算摄影学的一些函数工具。 |
| Stitching | 本模块是一个精巧的图像拼接流程实现。这是库中的新功能,但是,就像 Photo 模块一样,这个领域未来预计有很大的增长。 |
| Nonfree | 在 OpenCV 3.0 中,被移到 opencv_contrib/xfeatures2d。
OpenCV 包含一些受到专利保护的或者受到使用限制的(比如 SIFT 算法)算法。这些算法被隔离到它们自己的模块中,以表明你需要做一些特殊的工作,才可以在商业产品中使用它们。 |
| Contrib | 在 OpenCV 3.0 中,融合进了 opencv_contrib。
这个模块包含一些新的、还没有被集成进 OpenCV 库的东西。 |
| Legacy | 在 OpenCV 3.0 中,被取消。
这个模块包含一些老的尚未被完全取消的东西。 |
| ocl | 在OpenCV 3.0 中,被取消,取而代之的是 T-API。
这是一个较新的模块,可以认为它和 GPU 模块相似,它实现了开放并行编程的 Khronos OpenCL 标准。虽然现在模块的特性比 GPU 模块少很多,但 ocl 模块的目标是提供可以运行在任何 GPU 或者是其他可以搭载 Khronos 的并行设备。这与 GPU 模 块形成了鲜明的对比,后者使用 Nividia CUDA 工具包进行开发,因此只能在 Nividia GPU 设备上工作。 |
安装
在 Windows 系统下安装 OpenCV
在 Releases – OpenCV 可以发现最新的为 Windows 准备的最新版本 OpenCV 下载链接。可以通过这个链接下载一个 EXE 文件,该文件会把预编译好的 OpenCV 解压到你的电脑上,预编译版本支持不同版本的 Visual Studio 环境。现在,你很快就可以开始使用 OpenCV了。
注意:尽管 Windows 环境拥有预编译的 release 版本的库,但是它并不包含 debug 版本的库。所以,在开发 OpenCV 之前,需要打开解决方案并且自行编译那些库。
另一个额外的细节是,需要再添加一个名为OPENCV_DIR的环境变量来告诉编译器在哪里找到 OpenCV 的二进制文件。可以通过命令行工具(cmd)对此进行设置。
setx -m OPENCV_DIR D:\OpenCV\Build\x64\vc10
如果希望静态链接 OpenCV,就只需要做到这一步。如果希望使用 OpenCV 的动态链接库(DLL),就需要告诉系统在哪里找到它的二进制库。为了完成这一目标,只需要在库路径中添加%OPENCV_DIR%\bin。
以 Windows 10 为例,具体操作步骤是:右击计算机图标,选择“属性”,然后单击“高级系统设置”,最后选择“环境变量”,把 OpenCV 二进制文件的路径%OPENCV_DIR%\bin添加到 path 变量中。
OpenCV3 集成了 IPP,所以如果使用最新的 x86 或者 x64 CPU,就可以获得或多或少的性能优势。
从源代码编译 OpenCV
也可以按照如下操作从源码编译 OpenCV,具体步骤是:
- 运行 CMake GUI。
- 指定 OpenCV 源码所在路径以及构建目标文件夹(必须和源码所在路径不同)。
- 按两次 Configure 键(选择可以使用的 Visual Studio 编译器或者 MinGW 构建文件,如果正在使用 MinGW 的话),直到所有条目没有红色警示。
- 使用 Visual Studio 打开生成的解决方案并构建。如果使用的是 MinGW,则按照 Linux 的安装指导进行。
Linux 系统下安装 OpenCV
- GTK+ 2.x 或者更高的版本;
- GCC 编译器;
- cmake 构建工具;
- libtbb(英特尔线程构建模块);
- 还有一些可选项目,例如 zlib、libpng、libjpeg、libtiff 和 libjasper 的开发者版本(例如模块名称后带有
-dev的版本); - 你也需要用到 Python 2.6 或者更高的版本(开发者包)以及 NumPy 使 OpenCV 可以在 Python 环境下工作;
- 此外,还需要来自 ffmpeg 的 libavcodec 以及其他的 libav* 库(包含头文件)。
- /usr/local/lib/libavcodec.so.*
- /usr/local/lib/libavformat.so.*
- /usr/local/lib/libavutil.so.*
- 以及在 /usr/local/include/libav* 路径下的头文件
- 确定哪些例子需要被构建;
- 添加对 Python 的支持;
- 添加 CUDA GPU 的支持。
Mac系统下安装 OpenCV
- 在默认情况下,Cocoa 会取代 GTK+;
- 在默认情况下,QTKit 会取代 ffmpeg;
- GDC 会取代 TBB 以及 OpenMP。
从 Git 获取最新的 OpenCV
git clone https://github.com/opencv/opencv.git
给大家推荐一个国内OpenCV讲得最好的教程。
库的一般使用方法
为了用 C++ 开发一个 OpenCV 应用,需要在代码中:
- 包含 OpenCV 的头文件定义;
- 链接 OpenCV 库(二进制文件),以获取最终的可执行文件;
用这个指令,可以包含用户程序所需的每个头文件。另一方面,如果包含 opencv.hpp 头文件,那么所有的头文件都将被自动包含,如下所示:
注意,本地安装的所有模块都在 OPENCV_BUILD\install\include\opencv2\opencv_modules.hpp 头文件中定义,并在 OpenCV 的构建过程中自动生成。
#include 指令的使用并非总能保证对头文件的正确包含,因为告诉编译器在哪里能找到包含文件是有必要的。这一点可以通过传递具有文件位置的一个特殊参数来实现(例如,对于 GNU 编译器为 I\
)。
链接过程需要提供(动态或静态)链接库,在这里可以找到所需的 OpenCV 功能。这个过程通常用链接器的两种类型参数完成:库的位置(例如,GNU 编译器的 -L\
)和库的名字(例如,-l
)。
在 GCC online documentation- GNU Project 和 GNU Make Manual – GNU Project – Free Software Foundation 下,可以找到对于 GNU GCC 和 Make 可用的在线文档的一个完整列表。
开发新项目的工具
开发我们自己的 OpenCV C++ 应用的主要先决条件是:
- OpenCV 头文件和库二进制文件:当然,我们需要编译 OpenCV,并且对这样一个编译,辅助库是先决条件。该代码包应该使用与生成用户应用程序相同的编译器来编译。
- 一个 C++ 编译器:一些关联工具用作代码编辑器、调试器、项目管理器、构建过程管理器(例如,CMake)、修订控制系统(例如,Git、Mercurial、SVN 等)、类检测器等是方便的。通常,这些工具在一个集成开发环境(IDE)中一起进行配置。
- 任何其他辅助库:有时编写最终应用程序所需的任何其他辅助库,例如绘图、统计等,可能是需要的。
- Microsoft Visual C(MSVC):只在 Windows 上支持,与 IDE Visual Studio 集成得很好,当然也可以与其他跨平台的 IDE 集成,例如,Qt 生成器或 Eclipse。与目前最新的 OpenCV 发布兼容的 MSVC 版本是 VC 10、VC 11 和 VC 12(Visual Studio 2010、2012 和 2013)。
- GNU Compiler Collection GNU GCC:这是由 GNU 项目开发的一个跨平台的编译器系统。对于 Windows 来说,该工具包就是众所周知的 MinGW(最小的 GNU GCC)。与目前 OpenCV 发布兼容的版本是 GNU GCC 4.8。该工具包可以和若干 IDE 一起使用,例如,Qt 生成器、Code::Blocks、Eclipse 等。
注意,对于 Windows,可以从 http://qt-project.org/ 下载一个 Qt 包(包括 Qt 库、Qt 生成器和 MinGW 工具包)。这个包大约 700MB。
Qt 生成器是一个针对 C++ 的跨平台 IDE,它集成了我们编写应用时所需的工具。在 Windows 中,可以使用 MinGW 或 MSVC。图 1 展示了对于一个 OpenCV C++ 项目具有不同的面板和视图的 Qt 生成器的主窗口。

使用 Qt 生成器创建 OpenCV C++ 程序
TARGET: showImage TEMPLATE = app CONFIG += console CONFIG -= app_bundle CONFIG -= qt SOURCES += \ showImage.cpp INCLUDEPATH += C:/opencv300-buildQt/install/include LIBS += -LC:/opencv300-buildQt/install/x64/mingw/lib \ -lopencv_core300.dll \ -lopencv_imgcodecs300.dll\ -lopencv_highgui300.dll\ -lopencv_imgproc300.dll
注意,行尾的反斜线表示续行。
有关 Qt 项目开发中用到的工具(包括 Qt 生成器和 qmake)的详细描述,可访问 Qt Documentation | Home。
OpenCV 基本 API 概念
Mat(nrows,ncols,type,fillValue)
数组元素的初始值可以由 Scalar 类设置为一个典型的四元素向量(对于存储在数组中的图像的每个 RGB 和透明度分量)。下面展示 Mat 的一个使用示例:
DataType 类定义 OpenCV 的基本数据类型。基本数据类型可以是 bool、unsigned char、signed char、unsigned short、signed short、int、float、double 或者是以这些基本类型之一的值构成的一个元组(或称数组)。任何基本类型都可以用一个标识符以下面的形式定义:
CV_
{U|S|F}C(
)
enum{CV_8U=0,CV_8S=1,CV_16U=2,CV_16S=3,CV_32S=4,CV_32F=5,CV_64F=6};

- 在包含头文件后还应添加使用命名空间 cv 的声明(using namespace cv)(这是本书所有代码示例所使用的选项)。
- 对用到的所有 OpenCV 类、函数和数据结构上附加 cv:: 前缀。如果由 OpenCV 提供的外部名字与常用的标准模块库(standard template library,STL)或其他库冲突,那么就推荐使用这个选项。
OpenCV支持图像文件的格式
OpenCV 支持最常见的图像格式。但是,某些图像格式需要(免费提供的)第三方类库。由 OpenCV 支持的主要格式有:
- Windows bitmaps(*.bmp、*dib);
- Portable image formats(*.pbm、*.pgm、*.ppm);
- Sun rasters(*.sr、*.ras);
- JPEG(*.jpeg、*.jpg、*.jpe);
- JPEG 2000(*.jp2);
- Portable Network Graphics(*.png);
- TIFF(*.tiff、*.tif);
- WebP(*.webp);
OpenCV示例代码
为了说明如何使用 OpenCV 读、写图像文件,现在,我们将描述 showImage 示例,如图 2 所示。

\showImage.exe fruits.jpg fruits_bw.jpg
在本示例中,两个文件名称作为参数给出。第一个是读取的输入图像文件。第二个是使用输入图像的一个灰度副本写入的图像文件,接下来,展示源代码及其说明:
- #include
- #include
- using namespace std;
- using namespace cv;
- int main(int, char *argv[])
- {
- Mat in_image, out_image;
- // Usage:
- //读取原始图像
- in_image = imread(argv[1], IMREAD_UNCHANGED);
- if (in_image.empty()) {
- //检查是否读取图像
- cout << "Error! Input image cannot be read...\n";
- return -1;
- }
- //创建两个具有图像名称的窗口
- namedWindow(argv[1], WINDOW_AUTOSIZE);
- namedWindow(argv[2], WINDOW_AUTOSIZE>;
- //在之前创建的窗口中显示图片
- imshow(argv[1], in_image);
- cvtColor(in_image, out_image, COLOR BGR2GRAY);
- imshow(argv[2], in_image);
- cout << "Press any key to exit...\n";
- waitKey(); // Wait for key press
- //写入图像
- imwrite(argv[2], in_image);
- return 0;
- }
OpenCV读取图像文件
Mat imread(const String& filename,int flags = IMREAD_COLOR)
flag 指定读取图像的颜色,并在 imgcodecs.hpp 头文件中由如下枚举类型定义和解释:
- enum { IMREAD_UNCHANGED = -1, // 8 位,彩色或非彩色
- IMREAD_GRAYSCALE = 0, // 8 位,灰度
- IMREAD_COLOR = 1, //未改变深度、颜色
- IMREAD_ANYDEPTH = 2, //任意深度,未改变颜色
- IMREAD_ANYCOLOR = 4, //未改变深度,任意颜色
- IMREAD_LOAD_GDAL = 8 // 使用 gdaL 驱动程序
- };
void namedWindow(const String& winname,int flags = WINDOW_AUTOSIZE)
OpenCV 窗口是通过程序中一个意义明确的名字来识别的。通过下面 highgui.hpp 头文件中的枚举给出该标志的定义及其说明:
- enum { WINDOW_NORMAL = 0x00000000,
- //用户可以调整窗口的大小(无约束)
- //还可以将一个全屏窗口切换为常规窗口
- WINDOW_AUTOSIZE = 0x00000001,
- //用户不能调整窗口的大小,
- //窗口的大小由显示的图像所限制
- WINDOW_OPENGL = 0x00001000, // OpenGL 支持的窗口
- WINDOW_FULLSCREEN = 1,
- WINDOW_FREERATIO=0x00000100,
- //图像可任意使用(调整图像时可没有比例限制)
- WINDOW_KEE PRATIO = 0x00000000
- //调整图像时保持图像的缩放比例
- };
一个窗口的创建不会在屏幕上显示任何内容。在一个窗口中显示一幅图像的函数(属于 highgui 模块)是:
void imshow(const String& winname,InputArray mat)
在内部循环中处理事件
如果在一个窗口上显示一幅图像之后不再做任何事情,出乎意料地,将不再显示图像。在一个窗口显示一幅图像之后,我们应该开始一个循环,以获取和处理与用户和窗口交互有关的事件。通过如下函数可执行这样一个任务(从 highgui 模块中):
int waitKey(int delay=0)
这个函数在数毫秒(delay>0)内等待一个按键操作,并返回键的编码,如果延迟结束时没有按键则返回 -1。如果 delay 是 0 或负数,那么函数一直等待直到一个键被按下。
记住,只有至少创建和激活一个窗口时,函数 waitKey 才会工作。
OpenCV写入图像文件
imgcodecs 模块中的另一个重要函数是:
bool imwrite(const String& filename,InputArray img,const vector
& params=vector
())
这个函数将一幅图像(img)保存到一个文件(filename),作为第三个可选参数,一个“属性-值”对的向量指定编解码器的参数(为使用默认值将其设置为空)。编解码器由文件的扩展名决定。
- #include
- #include
- using namespace std;
- using namespace cv;
- int main(int, char )
- {
- Mat in_frame, out_frame;
- const char win1[]=”Grabbing…”, win2[]=”Recording…”;
- double fps=30;//每秒的帧数
- char file_out[]=”recorded.avi”;
- VideoCapture inVid(O) ; //打开默认摄像机
- if ( !inVid.isOpened () ) { //检查错误
- cout << "Error! Camera not ready...\n";
- return -1;
- }
- //获取输入视频的宽度和高度
- int width = (int)inVid.get(CAP_PROP_FRAME_WIDTH);
- int height = (int)inVid.get(CAP_PR〇P_FRAME_HEIGHT);
- VideoWriter recVid(file out,VideoWriter::fourcc(‘M’,’S’,’V’,’C’), fps, Size(width, height));
- if (!recVid.isOpened()) {
- cout << "Error! Video file not opened...\n";
- return -1;
- }
- //为原始视频和最终视频创建两个窗口
- namedWindow(win1);
- namedWindow(win2);
- while (true) {
- //从摄像机读取帧(抓取并解码)
- inVid >> in frame;
- //将帧转换为灰度
- cvtColor(in_frame, out_frame, C0L0R_BGR2GRAY);
- //将幀写入视频文件(编码并保存)
- recVid << out_frame ?
- imshow (win1, in_frame);// 在窗口中显示帧
- imshow(win2, out_frame); // 在窗口中显示帧
- if (waitKey(1000/fps) >= 0)
- break;
- }
- inVid.release(); // 关闭摄像机
- return 0;
- }
- double VideoCapture::get(int propId):这个函数为一个 VideoCapture 对象返回指定的属性值。在 videoio.hpp 头文件中包含了基于 DC1394(IEEE 1394 数码相机规范)属性的一个完整列表。
- static int VideoWriter::fourcc(char c1,char c2,char c3,char c4):这个函数把四个字符连接起来形成一个 fourcc 码。在示例中,MSVC 代表微软视频(仅在 Windows 上可用)。有效的 fourcc 码列表被发布在 http://www.fourcc.org/codecs.php 上。
- bool VideoWriter::isOpened():如果写入视频的对象被成功初始化,这个函数返回 true。例如,使用一个不正确的编解码器会产生一个错误。
注意,在一个系统中有效的 fourcc 码依赖于本地安装的编解码器。为了了解在本地系统中安装的 fourcc 编解码器是否可用,推荐 MediaInfo 上对很多平台都可用的开源工具 MediaInfo。
- VideoCapture&VideoCapture::operator>>(Mat&image):这个函数抓取、解码并返回下一帧。这个方法和布尔函数 VideoCapture::read(OutputArray image)等价。可以使用这个函数而不使用函数 VideoCapture::grab(),然后使用 VideoCapture::retrieve()。
- VideoWriter&VideoWriter::operator<<(const Mat&image):这个函数写入下一帧。这个方法和布尔函数 VideoWriter::write(const Mat&image)等价。 在本示例中,有一个读取/写入循环,可同时地获取并处理窗口事件。waitKey(1000/fps)函数调用负责执行这个任务。在这个示例中,1000/fps 表示返回外部循环之前等待的毫秒数。尽管不精确,但对于录制的视频仍能获取每秒帧数的一个近似度量。
- void VideoCapture::release():这个函数释放视频文件或采集设备。尽管在本示例中没有必要显式地包含,但为了说明它的使用,示例中仍包含了这个函数。
给大家推荐一个国内OpenCV讲得最好的教程。
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/200330.html原文链接:https://javaforall.net
