图像的许多操作与Numpy的关系比OpenCV关系更加紧密,如果熟练Numpy的话可以写出性能更好的代码。
1.读取显示保存图片
读取图片
1
2
3import cv2
#第一个参数为图片的相对路径,第二个参数为读取方式(cv2.IMREAD_COLOR、cv2.IMREAD_GRAYSCALE)
img = cv2.imread('image01.jpg', cv2.IMREAD_COLOR)(需注意的是当图片的路径填写有误,解释不会报错,但会得到一个None对象)
显示图片
1
2
3cv2.imshow('窗口名', img)
cv2.waitkey(0) #等待键盘输入
cv2.destroyAllWindows() #关闭窗口(cv2.waitkey()是一个键盘绑定方法,可以用来确定特殊键是否点击;另外也可以通过matplotlib显示图像,OpenCV加载图片是BGR模式,matplotlib是RGB模式)
保存图片
1
cv2.imwrite('messigery.jpg', img)
2.修改像素或灰度值
对于彩色图片一个像素点返回的是BGR像素,灰度图像返回的是灰度值
1 | img[x, y] = 100 #将(x,y)位置像素/灰度值改为100 |
3.获取图像基本属性
1 | print(img.shape) #获取形状:长、宽、通道数 |
4.图像ROI
有时需要在一幅图像的特殊区域工作。比如在一副图像中检测人眼的位置,应该是先找到人头部的区域,再在其中检测眼睛。这样提高程序的准确性和性能。
ROI是通过Numpy的索引获得的,如下图所示,把窗户的一部分拷贝到另一部分:
1 | selectArea = img[280:340,330:390] |
5.拆分合并图像通道
有时需要对图像的BGR三个通道单独进行操作或者合并成一个图像,实现如下:
1 | #将BGR格式图片转换为RGB格式的 |
6.图像扩边
1 | cv2.copyMakeBorder(img, top, bottom, left, right, 边界类型参数) |
7.图像上的算术运算
图像加方法
1
2
3
4
5
6x = np.uint8([250])
y = np.uint8([10])
#opencv加法是饱和操作
print cv2.add(x,y) # 250+10 = 260 => 255
#numpy加法是求模操作
print x+y # 250+10 = 260 % 256 = 4图像混合
图像混合其实也是图像加法的一种,不过是加上了权重:$dst = \alpha\cdot img1+\beta \cdot img2+\gamma$
1
2
3
4
5
6
7
8import cv2
import numpy as np
img1=cv2.imread('ml.png')
img2=cv2.imread('opencv_logo.jpg')
dst=cv2.addWeighted(img1,0.7,img2,0.3,0)
cv2.imshow('dst',dst)
cv2.waitKey(0)
cv2.destroyAllWindow()如下所示:
8.检测程序效率
运行时间检测
检测运行时间方法主要有两种:通过time.time()
和cv2.getTickCount()
:1
2
3
4
5
6import cv2
import numpy as np
e1 = cv2.getTickCount()
# your code execution
e2 = cv2.getTickCount()
time = (e2 - e1)/ cv2.getTickFrequency()默认优化
OpenCV中很多函数都被优化过(使用SSE2,AVX等)。也包含一些没有被优化的代码。如果系统支持的话要尽量利用这一点。在编译时优化是默认开启的。可以使用cv2.useOptimized()
来查看优化是否被开启,使用函数cv2.setUseOptimized()
来开启优化。效率优化技术
- 尽量避免使用循环
- 算法中尽量使用向量操作,因为Numpy和OpenCV都对向量操作进行了优化
- 使用高速缓存一致性
- 没有必要的话就不要复制数组。使用视图来代替复制。数组复制是非常浪
费资源的。