计算机视觉方向必备opencv基础知识总览
点击上方“小白学视觉”,选择加"星标"或“置顶”
重磅干货,第一时间送达
曾经看过一个视频,树莓派自平衡机器人自动追着小球跑。不经让我脑子蹦出一个有趣的想法,可以做一个识别猫的机器人,让机器人跟着猫跑,有这样一个小东西陪伴喵星人一定很有意思。
不过,首先你要有一只猫,其次,这个机器人不仅要有一双会视觉处理的眼睛,还一定要有一个坚强的外壳,不然会被喵星人给拆了。
那机器人是如何完成处理图像和视频的各项任务呢?开源的计算机视觉包——OpenCV 会是你的最佳选择,今天给小白们做一个最简单的入门介绍。
今天很开心与大家分享一篇关于OpenCV的文章,重点阐述以下几个问题:
1.如何部署OpenCV。
2.OpenCV有哪些模块,可以做什么。
3.OpenCV的基本数据结构的熟悉与使用。
希望看过文章后,你也可以开始玩转OpenCV之路。


它是一款由Intel公司俄罗斯团队发起并参与和维护的一个计算机视觉处理开源软件库。
作为一款优秀的计算机视觉库,在诸多方面都有着卓越的表现:
1.编程语言
多数模块基于C++实现,少部分基于C语言实现,同时提供了Python、Ruby、MATLAB等语言的接口。
2.跨平台
可自由地运行在Linux、Windows和Mac OS等桌面平台,Android、 IOS、BlackBerray等移动平台。
3.活跃的开发团队
目前已更新至OpenCV4.0
4.丰富的API
完善的传统计算机视觉算法,涵盖主流传统机器学习算法,同时添加了对深度学习的支持。
OpenCV可以完成几乎所有的图像处理任务,下面是一个简要list。
- 视频分析(Video analysis) 
- 3D重建(3D reconstruction) 
- 特征提取(Feature extraction) 
- 目标检测(Object detection) 
- 机器学习(Machine learning) 
- 计算摄影(Computational photography) 
- 形状分析(Shape analysis) 
- 光流算法(Optical flow algorithms) 
- 人脸和目标识别(Face and object recognition) 
- 表面匹配(Surface matching) 
- 文本检测和识别(Text detection and recognition) 

一般来说我们会使用OpenCV的C++和Python版本,所以下面分别对其安装进行介绍,以ubuntu系统为例。
2.1 Ubuntu安装C++ OpenCV
安裝OpenCV所需的库
sudo apt-get install build-essential
sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev
libswscale-dev3 sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev 
下载最新opencv源码
unzip opencv-3.2.0.zip
cd ~/opencv-3.2.0 
编译OpenCV
cd ~/opencv-3.2.0
mkdir release
cd release
cmake -D CMAKE_BUILD_TYPE=RELEASE -D
CMAKE_INSTALL_PREFIX=/usr/local ..
make
sudo make install
一般来说,编译安装绝对不可能一次顺利完成,以下是几个常见的问题。
1,编译过程中ippcv下载失败, 解决问题的办法就是手动下载。
2,LAPACK包include报错, 解决问题的办法就是在cmake之后马上修改对应include文件的路径 如果make失败后再修改则无效。
3,某些模块找不到, 通常是因为少了编译安装contrib模块。
2.2 Ubuntu安装Python-OpenCV
安装opencv
pip3 install opencv-python
进入python,导入cv2
import cv2

OpenCV提供了许多内置的用于图像处理和计算机视觉相关操作的基础数据结构,它们都包含在core模块中,并且这些数据结构都已经针对速度和内存做了优化,下面以4.0版本为例进行介绍,参考https://docs.opencv.org/master/d9/df8/tutorial_root.html。
Opencv目录下”modules目录”列出了OpenCV包含的各个模块,其中core、highgui、imgproc是最基础的模块。

- core模块实现了最核心的数据结构及其基本运算,如绘图函数、数组操作相关函数,与OpenGL的互操作等。 
- highgui模块实现了视频与图像的读取、显示、存储等接口。 
- imgproc模块实现了图像处理的基础方法,包括图像滤波、图像的几何变换、平滑、阈值分割、形态学处理、边缘检测、目标检测、运动分析和对象跟踪等。 
对于图像处理其他更高层次的方向及应用,OpenCV也有相关的模块实现
- features2d模块用于提取图像特征以及特征匹配,nonfree模块实现了一些专利算法,如sift特征。 
- objdetect模块实现了一些目标检测的功能,经典的基于Haar、LBP特征的人脸检测,基于HOG的行人、汽车等目标检测,分类器使用Cascade Classification(级联分类)和Latent SVM等。 
- stitching模块实现了图像拼接功能。 
- FLANN模块(Fast Library for Approximate Nearest Neighbors),包含快速近似最近邻搜索FLANN 
 和聚类Clustering算法。
- ml模块机器学习模块(SVM,决策树,Boosting等等)。 
- photo模块包含图像修复和图像去噪两部分。 
- video模块针对视频处理,如背景分离,前景检测、对象跟踪等。 
- calib3d模块即Calibration(校准)3D,这个模块主要是相机校准和三维重建相关的内容。包含了基本的多视角几何算法,单个立体摄像头标定,物体姿态估计,立体相似性算法,3D信息的重建等等。 
- G-API模块包含超高效的图像处理pipeline引擎。 
另外,原来在opencv2中的shape, superres, videostab, viz等模块被移动到opencv_contrib中,关于opencv contrib,我们以后再详细介绍。

OpenCv提供了多种基本的数据类型,常用的OpenCV的基本数据结构有以下几种:
- Mat类 
- Point类 
- Size类 
- Rect类 
- Scalar类 
- Vec类 
- Range类 

下面我们重点说一下MAT类。
4.1 Mat类
要熟练使用OpenCV,最重要的就是学会Mat数据结构,在OpenCV中Mat被定义为一个类,把它看作一个数据结构,以矩阵的形式来存储数据的。
Mat有哪些常见的属性?
- dims:表示矩阵M的维度,如2*3的矩阵为2维,3*4*5的矩阵为3维 
- data:uchar型的指针,指向内存中存放矩阵数据的一块内存 
- rows, cols:矩阵的行数、列数 
- type:表示了矩阵中元素的类型(depth)与矩阵的通道个数(channels);命名规则为CV_ + (位数)+(数据类型)+(通道数) - 其中:U(unsigned integer)-- 无符号整数 - S(signed integer)-- 有符号整数 - F(float)-- 浮点数 - 例如CV_8UC3,可拆分为:CV_:type的前缀, - 8U:8位无符号整数(depth),C3:3通道(channels) 
- depth:即图像每一个像素的位数(bits);这个值和type是相关的。例如CV_8UC3中depth则是CV_8U。 
- channels:通道数量,若图像为RGB、HSV等三通道图像,则channels = 3;若图像为灰度图,则为单通道,则channels = 1 
- elemSize:矩阵中每一个元素的数据大小 - elemSize = channels * depth / 8 - 例如:type是CV_8UC3,elemSize = 3 * 8 / 8 = 3bytes 
- elemSize1:单通道的矩阵元素占用的数据大小 
elemSize1 = depth / 8
例如:type是CV_8UC3,elemSize1 = 8 / 8 = 1bytes
4.2 其他数据类型
1.点Point类
包含两个整型数据成员x和y,即坐标点
2.尺寸Size类
数据成员是width和height,一般用来表示图像的大小,或者矩阵的大小
3.矩形Rect类
数据成员x,y,width,height,分别代表这个矩形左上角的坐标点和矩形的宽度和高度
4.颜色Scalar类
Scalar_(_Tp v0, _Tp v1, _Tp v2=0, _Tp v3=0)
这个默认构造函数的四个参数分别表示RGB+Alpha颜色中的:
v0---表示RGB中的B(蓝色)分量
v1---表示RGB中的G(绿色)分量
v2---表示RGB中的R(红色)分量
v3---表示Alpha是透明色分量
5.向量Vec类
一个“一维矩阵”
Vec
6.Range类
用于指定一个连续的子序列,例如一个轮廓的一部分,或者一个矩阵的列空间

这里使用的是python接口
1.图像读写
cv2.imread(文件名,显示控制参数) # 读入图像
cv2.imshow(窗口名,图像名) #显示图像
cv2.imwrite(文件地址,文件名) #保存图像
cv2.namedWindow(窗口名) #创建窗口
cv2.destroyAllWindows() #销毁窗口
cv2.waitKey( [,delay]) #decay > 0 等待delay 毫秒
#decay < 0 等待键盘单击
#decay = 0 无限等待

2.图像缩放
dst = cv2.resize(src,dsize,fx,fy) #dsize表示缩放大小
#fx,fy缩放比例
3.图像翻转
dst = cv2.flip(src,flipCode)
#flipCode=0 以X轴为对称轴的翻转
#lipCode>0 以Y轴为对称轴的翻转
#flipCode<0 对X、Y轴同时翻转

4.通道拆分与合并
b,g,r = cv2.split(图像)
b = cv2.split(图像)[通道数] #拆分
bgr = cv2.merge([b,g,r]) #合并


6.1 网络资料
- OpenCV Docs官方文档 - https://docs.opencv.org/ 
- OpenCV 官方Github - https://github.com/opencv/opencv 
- OpenCV 中文教程 - http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/tutorials.html 
6.2 中文书籍
- Python计算机视觉编程 
- OpenCV 3计算机视觉:Python语言实现 
- OpenCV算法精解:基于Python与C++ 
最后,推荐一下大家的Opencv学习路线。

好消息,小白学视觉团队的知识星球开通啦,为了感谢大家的支持与厚爱,团队决定将价值149元的知识星球现时免费加入。各位小伙伴们要抓住机会哦!

交流群
欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

