前言
python强大有一个很重要的原因是它有着数量庞大、涉及领域广泛且专业实用的第三方库,就我所接触到就有:
- 数据分析、科学计算: numpy、scipy、pandas
- 图像处理: OpenCV、PIL
- 数据可视化: matplotlib
- 网络: uillib2、scrapy、django
- UI界面: pyqt、Thinker
知乎上更是有网友总结非常全面的总结。因此要使用python解决实际的项目,除了要熟悉python的基本语法外,还要查看一大堆第三方库的资料。每次查找资料是很费时间的,所以熟悉这些常用的第三方库的基本用法就显得很重要了,因为python很高的开发效率是它的优势,如果又因为这些原因有导致开发效率降低了,就完全达不到使用的目的了。
本篇文章仅仅对python的openCV、numpy和matplotlib这三个库的简单使用做些整理。
环境问题
OpenCV的支持
python的库多,而且又相互依赖,如OpenCV对numpy就严重依赖,所以选择发行版本WinPython或者Anacoda减少这方面的影响,但是即使是发行版一般OpenCV的也是没有带的。
安装Python对OpenCV的支持一般方法是:将openCV库的“build\python\2.7\”目录中的cv2.pyd文件复制到python的“Lib\site-packages\”文件夹中。
不过当前OpenCV仅仅提供2.7的支持,如果使用python3就只能下载非官方的支持,如下位Windows下python第三方库安装包整理得很全面得网站,在上面找到python和OpenCV对应的版本下载安装:
Unofficial Windows Binaries for Python Extension Packages:http://www.lfd.uci.edu/~gohlke/pythonlibs/
这个网站上提供的都是.whl为后缀名的文件,需要使用pip工具安装。安装方法为打开命令行界面,输入:
1
pip install 安装文件名
pip工具的安装
pip上python中安装第三方库最常用的工具,但是一般python也没有自带,需要手动安装。pip官方下载地址为:https://pypi.python.org/pypi/pip
在上面下载pip的压缩包“pip-9.0.1.tar.gz”,解压后在解压后的文件夹中,打开命令行,执行:
1
python setup.py install
OpenCV的使用
OpenCV python版有官方文档介绍使用,是但比起C++,就显得很不不详细了。它可以提供快速入门指导,但是却无法提供其API结构更详细的说明,所以只能从C++对应的方法来推测。官方文档地址为:https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_tutorials.html
OpenCV的python版使用与在C++还是会稍有区别,其中最大不同就是使用了numpy来代替了C++中的mat。
读入图像
使用imread函数代码,其返回的是一个numpy.ndarray类型的多维数组,记录图像的每个pixel的原始数据,使用这个返回值,可以直接使用numpy中的各种方法,很放方便的处理图像中任意像素点的原始数据,当然如果OpenCV已经又现成的方法,就可以不用手动使用numpy去处理了:
1
2import cv2
imgdata = cv2.imread(fileName)显示图像
使用imshow显示图像,固定的操作,值得注意的是waitKey函数是阻塞的,在关闭窗口前程序不能向下运行。
1
2
3
4cv2.namedWindow('image', cv2.WINDOW_NORMAL)
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()保存图像
使用imwrite函数保存图像到文件
1
cv2.imwrite('messigray.png',img)
以上为OpenCV对图像的基本操作,不过使用OpenCV的最大的好处实际上很方便的用到其强大的图像处理算法,所以对这些算法操作需要查看文档。
Numpy的使用
Numpy是python中最基础的科学计算类库,很多其他库都需要它的支持,正因为如此,Numpy的数组几乎成为了python中除基本数据结构外最重要的类型了。它最主要的目的是为python提供多维数据的类型。一般在python中,简单的序列操作,可以用list这个python内置的数据结构来实现,但是如果是大量数字类型的运算计算,使用Numpy不仅在执行速度会更高效,而且代码上会更简介。
对比list,numpy有如下特点:
- numpy数组的size是固定的,改变其size将创建新的numpy数组
- numpy数组的元素必须全部都是一样的
- numpy数组是高度优化的,处理数学计算是高效且方便
- numpy可以提供类似matlab类似的,将行或列或者是一个整体当作一个基本元素来进行计算操作
ndarray类型
ndarray是Numpy的基本对象,是表示多维数组的数据类型,它的属性有:
- ndarray.ndim: 维度
- ndarray.shape: 尺寸形状
- ndarray.size: 所有元素的数量
- ndarray.dtype: 元素的类型
- ndarray.itemsize: 元素占字节数
- ndarray.data: 所有元素集合
创建ndarray类型
- 使用np.array函数: np.array([2,3,4])
- 使用np.zeros函数,创建并将元素初始化为零: np.zeros((3,4))
- 使用np.ones函数,创建并将元素初始化为一: np.ones((2,3,4), dtype=np.int16)
- 使用np.empty函数,创建但不初始化: np.empty( (2,3) )
- 使用np.arange函数,创建等差序列: np.arange( 10, 30, 5 )
ndarray常用的方法
- reshape: 改变形状
- flatten: 将多维的数据整理成1维
- astype: 讲多维数据中的元素的类型转换为指定类型
- amin: 获取多维数据或者每一个行列的最小值
- amax: 获取多维数组或者每一个行列的最大值
- mean: 获取多维数组算数平均值或者每一个行列的平均值
- std: 获取多维数组的标准差或每一个行列的标准差
- var: 获取多维数组的方差或每一个行列的方差
matplotlib的使用
matplotlib是python中最常用的数据图标显示库,它类似与matlab能够画出多种类型的图标,官方网站为:http://matplotlib.org/index.html。但是由于matplotlib是能够化画的图标太多,推荐可以直接从例子上学习,地址为:http://matplotlib.org/gallery.html
导入模块
一般使用matplotlib画图都是从matplotlib.pyplot模块开始:
1
import matplotlib.pyplot as plt
画曲线图
使用plot函数可以画曲线图,plot函数有很多参数,最简单的就是只传入一个一维的数组,如下所示:
1
plt.plot(data)
除了在plot函数设置参数来设置画图属性外,在plot函数后,仍然可以通过使用setp函数来设置所画图表的属性:
1
plt.setp(lines, color='r', linewidth=2.0)
显示图表和关闭图表
显示图像很简单,直接使用show函数,可以显示前面所画的图表:
1
plt.show()
关闭图表同样简单,使用close函数即可,但是要注意的是在调用了show函数之后,程序是阻塞的状态,不会向下运行,所以在show函数使用close是没有用的。
1
plt.close()
子图表
在一个窗口中显示多张图表,最常用的函数是subplot,使用subplot函数可以将整个窗口分割成几行几列,在每个小格子中放置一个图表,如下代码表示,将窗口分割成2行1列,并指定在第一个小格子中画图。
1
2plt.subplot(211)
plt.plot(t2, np.cos(2*np.pi*t2), 'r--')如果希望子图像大小能够自己定制,如某子图像多占几个格子,则需要使用matplotlib.gridspec模块,使用GridSpec函数分割窗口,使用subplot函数传入所占格子的位置和多少,确定图表区域,后面在使用subplot函数返回值来画图。如下面的代码第三个图就占用了第二行的两列。
1
2
3
4
5import matplotlib.gridspec as gridspec
gs = gridspec.GridSpec(2,2)
ax1 = plt.subplot(gs[0,0])
ax2 = plt.subplot(gs[0,1])
ax3 = plt.subplot(gs[1,0:])调整子图表的位置和边距
使用update函数可以调整,子图表的边距和位置
1
gs.update(left=0.05, right=0.98, top=0.98, bottom=0.05, wspace=0.1)
另外一个简单的方法是,直接调用tight_layout函数,系统会根据实际情况自动调整到一个默认合适的位置。
1
plt.tight_layout()
画分布图
使用hist函数,画统计分布图,如下代码,其中hist函数第二个参数表示将数组分组统计的分组数据多少,normed表示归一化;hist的返回值中n表示每个分组中数据出现的统计次数或者频率,bins表示每个分组的两个边界值。
1
n, bins, patches = hist(data, 256, normed=1, facecolor='g', alpha=0.75)
曲面图
用matplotlib可以画三维图像,曲面图是一类比较简单的三维图,使用plot_surface函数可以画曲面图:
1
2
3
4
5
6from matplotlib import cm
n, m = arrayData.shape
x = np.arange(m)
y = np.arange(n)
X,Y = np.meshgrid(x,y)
surf = self.axlist[2].plot_surface(X, Y, arrayData, cmap=cm.coolwarm, linewidth=0)注意以上代码,X和Y都是二维数组,表示底部平面的上的每一个点,获取方法为:通过np得到其行和列的一维数组,使用meshgrid生成。