目录
书名 | 出版日期 | 实验环境 | 简要评价 |
---|---|---|---|
《学习OpenCV》 | 2009.10 | OpenCV作者所著,经典教材 | |
☆《OpenCV 3计算机视觉:Python语言实现(原书第2版)》 | 2016.6 | py2.7 | 通过Python开发基于OpenCV 3.0的应用,勘误,Github源码,第一版的Github源码,疑似第一版Github源码 |
《基于OpenCV的计算机视觉技术实现》 | 2008.5 | OpenCV1.0 | 有讲解立体视觉的部分(照相机定标、三维重建) |
☆《OpenCV图像处理编程实例》 | 2016.5 | VS2015、OpenCV3.1.0 | 以功能介绍,勘误,谷歌到的PDF和源码 |
《OpenCV编程案例详解》 | 2016.10 | OpenCV3.0 | 以实例介绍,与QT配合,有配套网易云课堂的课程,源码见QQ群 |
《OpenCV和Visual Studio图像识别应用开发》 | 2017.10 | VS2013、OpenCV2.4.10 | 分模块介绍 |
《OpenCV图像处理》 | 2016.3 | OpenCV3.0 | Qt |
《OpenCV计算机视觉编程攻略:第2版》 | 2015.9 | OpenCV2.4.9 | |
《深入理解OpenCV:实用计算机视觉项目解析》 | 2014.9 | OpenCV | 高级应用,涉及Android、iOS |
《OpenCV项目开发实战》 | 2016.9 | OpenCV | 高级应用,涉及Unity |
☆《OpenCV3编程入门》 | 2015.2 | VS2010、OpenCV2.4.9、OpenCV3.0 | 分模块介绍,作者Github,作者博客,勘误 |
《OpenCV实例精解》 | 2016.8 | OpenCV | |
《数字图像处理基础及OpenCV实现》 | 2014.12 | VS2015、OpenCV1.0 | 教科书 |
《OpenCV 3计算机视觉:Python语言实现(原书第2版)》
CH1 安装OpenCV
OpenCV官网
OpenCV源码
OpenCV文档
python示例
1 | pip install opencv-python |
CH2 处理文件、摄像头和图形用户界面
基本I/O脚本
读/写图像文件
imread()、imwrite()
1 | import numpy as np |
图像与原始字节之间的转换
1 | import numpy as np |
使用numpy.array访问图像数据
1 | import numpy as np |
视频文件的读/写
VideoCapture类、VideoWriter类1
2
3
4
5
6
7
8
9
10
11
12# 读取AVI文件的帧,并采用YUV颜色编码将其写入另一个帧中
import cv2
videoCapture = cv2.VideoCapture('MyInputVid.avi')
fps = videoCapture.get(cv2.CAP_PROP_FPS)
size = (int(videoCapture.get(cv2.CAP_PROP_FRAME_WIDTH)), int(videoCapture.get(cv2.CAP_PROP_FRAME_HEIGHT)))
videoWriter = cv2.VideoWriter('MyInputVid.avi', cv2.VideoWriter_fourcc('I','4','2','0'), fps, size)
success, frame = videoCapture.read()
while success:
videoWriter.write(frame)
success, frame = videoCapture.read()
常见编解码器(cv2.VideoWriter_fourcc()的第一个参数)
参数 | 作用 |
---|---|
‘I’,’4’,’2’,’0’ | 未压缩的YUV颜色编码,是4:2:0色度子采样,扩展名.avi |
‘P’,’I’,’M’,’1’ | MPEG-1编码类型,扩展名.avi |
‘X’,’V’,’I’,’D’ | MPEG-4编码类型,扩展名.avi |
‘T’,’H’,’E’,’O’ | Ogg Vorbis,扩展名.ogv |
‘F’,’L’,’V’,’1’ | Flash视频,扩展名.flv |
捕获摄像头的帧
1 | # 捕获摄像头10秒的视频信息,并将其写入一个AVI文件中 |
在窗口显示图像
imshow()1
2
3
4
5
6
7
8# 显示一副图像(保证显示视频时窗口上的帧一直更新)
import cv2
import numpy as np
img = cv2.imread('my-image.png')
cv2.imshow('my image', img)
cv2.waitKey()
cv2.destroyAllWindows()
在窗口显示摄像头帧
1 | # 实时显示摄像头帧 |
Cameo项目(人脸跟踪和图像处理)——面向对象的设计
见managers.py、cameo.py
CH3 使用OpenCV 3处理图像
不同色彩空间的转换
计算机视觉中3种常用的色彩空间:
- 灰度色彩空间——去除彩色信息
- BGR——蓝、绿、红
- HSV——色调、饱和度、黑暗的程度
傅里叶变换
傅里叶:一切都可以用波形来描述,所有的波形都可以由一系列简单且频率不同的正弦曲线叠加得到。
图像的幅度谱:呈现了原始图像在变化方面的一种表示,把一幅图像中最明亮的像素放到图像中央,然后逐渐变暗,在边缘上的像素最暗。
边缘检测/线段检测/形状检测以高通/低通滤波器和傅里叶变换为基础。
高通滤波器(HPF)
核(kernel)=滤波器矩阵=一组权重的集合=应用在源图像的一个区域,并由此生成目标图像的一个像素
用处:边缘检测
hpf.py1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28# 高通滤波器
import cv2
import numpy as np
from scipy import ndimage
kernel_3x3 = np.array([[-1, -1, -1],
[-1, 8, -1],
[-1, -1, -1]])
kernel_5x5 = np.array([[-1, -1, -1, -1, -1],
[-1, 1, 2, 1, -1],
[-1, 2, 4, 2, -1],
[-1, 1, 2, 1, -1],
[-1, -1, -1, -1, -1]])
img = cv2.imread("statue_small.jpg", 0) #将读入的图像转换为灰度格式
k3 = ndimage.convolve(img, kernel_3x3) #用给定的核与图像进行“卷积”(convolve)
k5 = ndimage.convolve(img, kernel_5x5)
blurred = cv2.GaussianBlur(img, (17,17), 0)
g_hpf = img - blurred #实现高通滤波器的另一种方法:通过对图像应用低通滤波器后,与原始图像计算差值——此方法效果最好
cv2.imshow("3x3", k3)
cv2.imshow("5x5", k5)
cv2.imshow("g_hpf", g_hpf)
cv2.waitKey()
cv2.destroyAllWindows()
低通滤波器(LPF)
用处:去噪、模糊化
见filters.py、utils.py
Canny边缘检测
Canny边缘检测的5个步骤:
- 用高斯滤波器对图像进行去噪
- 计算梯度
- 在边缘上使用非最大抑制(NMS)
- 在检测到的边缘上使用双阈值去除假阳性(false positive)
- 分析所有的边缘及其之间的连接
canny.py1
2
3
4
5
6
7
8
9# Canny边缘检测
import cv2
import numpy as np
img = cv2.imread("statue_small.jpg", 0)
cv2.imwrite("canny.jpg", cv2.Canny(img, 200, 300))
cv2.imshow("canny", cv2.imread("canny.jpg"))
cv2.waitKey()
cv2.destroyAllWindows()
轮廓检测
检测图像或视频帧中物体的轮廓、计算多边形边界、形状逼近、计算感兴趣区域
cv2.findContours()
contours.py1
2
3
4
5
6
7
8
9
10
11
12
13
14# 检测矩形轮廓(熟悉API)
import cv2
import numpy as np
img = np.zeros((200, 200), dtype=np.uint8)
img[50:150, 50:150] = 255
ret, thresh = cv2.threshold(img, 127, 255, 0)
image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) #输入参数(输入图像、层次类型、轮廓逼近方法),返回值(修改后的图像、图像的轮廓、它们的层次)
color = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
img = cv2.drawContours(color, contours, -1, (0,255,0), 2)
cv2.imshow("contours", color)
cv2.waitKey()
cv2.destroyAllWindows()
边界框、最小矩形区域、最小闭圆的轮廓
cv2.findContours()、cv2.boundingRect()、cv2.rectangle()
cv2.minAreaRect()、cv2.boxPoints()、 cv2.drawContours()
cv2.minEnclosingCircle()、cv2.circle()
contours_2.py1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38import cv2
import numpy as np
img = cv2.pyrDown(cv2.imread("hammer.jpg", cv2.IMREAD_UNCHANGED))
ret, thresh = cv2.threshold(cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY) , 127, 255, cv2.THRESH_BINARY)
image, contours, hier = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
# step1:计算出一个简单的边界框
# find bounding box coordinates
x,y,w,h = cv2.boundingRect(c) #返回(x,y)坐标、矩形的高度和宽度
cv2.rectangle(img, (x,y), (x+w, y+h), (0, 255, 0), 2)
# step2:计算出包围目标的最小矩形区域
# find minimum area
rect = cv2.minAreaRect(c)
# calculate coordinates of the minimum area rectangle
box = cv2.boxPoints(rect)
# normalize coordinates to integers
box = np.int0(box)
# draw contours
cv2.drawContours(img, [box], 0, (0,0, 255), 3)
# step3:检查的边界轮廓为最小闭圆
# calculate center and radius of minimum enclosing circle
(x,y),radius = cv2.minEnclosingCircle(c) #返回圆心的坐标组成的元组、圆的半径值
# cast to integers
center = (int(x),int(y))
radius = int(radius)
# draw the circle
img = cv2.circle(img,center,radius,(0,255,0),2)
cv2.drawContours(img, contours, -1, (255, 0, 0), 1)
cv2.imshow("contours", img)
cv2.waitKey()
cv2.destroyAllWindows()
凸轮廓与Douglas-Peucker算法
cv2.approxPolyDP()、 cv2.arcLength()、cv2.convexHull()
contours_hull.py1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21import cv2
import numpy as np
img = cv2.pyrDown(cv2.imread("hammer.jpg", cv2.IMREAD_UNCHANGED))
ret, thresh = cv2.threshold(cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY) , 127, 255, cv2.THRESH_BINARY)
black = cv2.cvtColor(np.zeros((img.shape[1], img.shape[0]), dtype=np.uint8), cv2.COLOR_GRAY2BGR)
image, contours, hier = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
epsilon = 0.01 * cv2.arcLength(cnt,True) #获取轮廓的周长信息
approx = cv2.approxPolyDP(cnt,epsilon,True) #输入参数(轮廓、ε值-源轮廓与近似多边形的最大差值、布尔标记-多边形是否闭合)
hull = cv2.convexHull(cnt) #获取处理过的轮廓信息
cv2.drawContours(black, [cnt], -1, (0, 255, 0), 2)
cv2.drawContours(black, [approx], -1, (255, 255, 0), 2)
cv2.drawContours(black, [hull], -1, (0, 0, 255), 2)
cv2.imshow("hull", black)
cv2.waitKey()
cv2.destroyAllWindows()
直线和圆检测
Hough变换
HoughLines() 标准的Hough变换
HoughLinesP() 概率Hough变换
HoughCircles() 检测圆
直线检测
hough_lines.py1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17# 直线检测
import cv2
import numpy as np
img = cv2.imread('lines.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray,50,120)
minLineLength = 20
maxLineGap = 5
lines = cv2.HoughLinesP(edges,1,np.pi/180,20,minLineLength,maxLineGap) #输入参数(需要处理的图像、线段的集合表示rho、theta、阈值-低于该阈值的直线会被忽略、最小直线长度-更短的直线会被消除、最大线段间隙-大于这个值会被视为是两条分开的线段)
for x1,y1,x2,y2 in lines[0]:
cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)
cv2.imshow("edges", edges)
cv2.imshow("lines", img)
cv2.waitKey()
cv2.destroyAllWindows()
圆检测
hough_circles.py1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23# 圆检测
import cv2
import numpy as np
planets = cv2.imread('planet_glow.jpg')
gray_img = cv2.cvtColor(planets, cv2.COLOR_BGR2GRAY)
img = cv2.medianBlur(gray_img, 5)
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,120,param1=100,param2=30,minRadius=0,maxRadius=0) #参数包括:圆心间的最小距离、圆的最小及最大半径
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
# draw the outer circle
cv2.circle(planets,(i[0],i[1]),i[2],(0,255,0),2)
# draw the center of the circle
cv2.circle(planets,(i[0],i[1]),2,(0,0,255),3)
cv2.imwrite("planets_circles.jpg", planets)
cv2.imshow("HoughCirlces", planets)
cv2.waitKey()
cv2.destroyAllWindows()
检测其他形状
cv2.approxPolyDP()、cv2.findContours()
CH4 深度估计与分割——没细看
使用深度摄像头(如微软的Kinect)的数据来识别前景区域和背景区域,需要自己构建OpenCV
两种方法:使用深度摄像头来进行深度估计、使用立体图像来进行深度估计
本章涉及的主题:深度估计和分割,介绍了深度摄像头、极几何、立体图像、视差图的计算、两种图像分割的流行方法(GrabCut、分水岭)
CH5 人脸检测和识别
特征描述符、关键点检测
CH6 图像检索以及基于图像描述符的搜索
CH7 目标检测与识别
CH8 目标跟踪
CH9 基于OpenCV的神经网络简介
《OpenCV3编程入门》
OpenCV各模块功能 P8
OpenCV2.0与OpenCV3.0的区别
OpenCV2.0:各个模块以整体的形式构建然后组合在一起
OpenCV3.0:内核+插件官方例程引导与赏析
示例代码路径:
D:_imv\opencv\sources\samples\cpp\tutorial_code
D:_imv\opencv\sources\samples\cpp编译OpenCV源代码 P45
argc与argv
int argc表示命令行字串的个数
char *argv[]表示命令行参数的字符串
配置VS2012+OpenCV2.4.9
参考博文
VS2012官方免费中文旗舰版下载(含激活密钥)
安装visual studio 2012,并配置opencv
VC与VS对应关系
VC | VS |
---|---|
VC8 | VS2005 |
VC9 | VS2008 |
VC10 | VS2010 |
VC11 | VS2012 |
VC12 | VS2013 |
VC14 | VS2015 |
VC15 | VS2017 |