Python进阶——OpenCV之Core Operations
文章目录
- 图像基本操作
- 访问并修改像素值
- 访问图像的属性
- 设置图像区域
- 图像分割与合并
- 画图像边框
- 图像的数学操作
- 图像叠加
- 图像融合
- 图像位操作
- Python OpenCV代码检测与速度优化
时隔一个月,续接上一篇,接着学习Core Operations。中间研究了下怎么用Python+opencv实现录屏,耽搁了一个星期时间,不过也巩固了第一篇的内容。
opencv的 Core Operations操作主要是跟numpy模块有关,因此还提前看了一下numpy模块的用法,关于这个模块的介绍有很多,这里就不对numpy做过多的说明了。
图像基本操作
访问并修改像素值
>>> import cv2>>> import numpy as np>>> img = cv2.imread('messi5.jpg')>>> px = img[100,100]>>> print px[157 166 200]# accessing only blue pixel,opencv图像存储为大端格式:BGR>>> blue = img[100,100,0]>>> print blue157>>> green = img[100,100,1]>>> print green166>>> red = img[100,100,2]>>> print red200# modify the pixel values>>> img[100,100] = [255,255,255]>>> print img[100,100][255 255 255]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
Numpy 是经过优化的快速矩阵计算库,单独读写某一个像素点速度很慢,以上几个像素操作方法,其实更适合操作一个图像区域。如果要操作单个像素点,推荐使用array.item() and array.itemset()
# accessing RED value>>> img.item(10,10,2)59# modifying RED value>>> img.itemset((10,10,2),100)>>> img.item(10,10,2)100
1
2
3
4
5
6
7
1
2
3
4
5
6
7
访问图像的属性
图像的属性主要包括图像的行、列、像素的通道数、图像的类型、像素的个数等。以下几个函数主要访问图像的属性。
# img.shape属性返回图像的行、列、颜色通道数(如果是彩色图像)# 如果是灰度图像,此属性只返回图像的行、列大小>>> print img.shape(342, 548, 3)# 图像的总像素个数>>> print img.size562248#图像每一个像素数据类型>>> print img.dtypeuint8#img.dtype is very important while debugging because a large number of errors in OpenCV-Python code is caused by invalid datatype.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
设置图像区域
典型操作,例如人眼检测,最好先进行人脸检测,然后在检测到的人脸范围内进行人眼检测,眼睛总是在脸上,因此先进行脸部检测,可以大大缩小眼睛检测的范围。从而提高人眼检测速度。
图像的区域操作同样使用numpy
# 将图像的一个区域复制到另一个区域>>> roi = img[280:340, 330:390]>>> img[273:333, 100:160] = roi
1
2
3
1
2
3
图像分割与合并
>>> b,g,r = cv2.split(img)>>> img = cv2.merge((b,g,r))#切片操作>>> b = img[:,:,0]>>> img[:,:,2] = 0
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
cv2.split()
函数是一个耗时操作,谨慎使用。
画图像边框
cv2.copyMakeBorder()
函数用于为图像画边框 ,函数的参数说明如下:
- src - input image
- top, bottom, left, right - border width in number of pixels in corresponding directions
- borderType - Flag defining what kind of border to be added. It can be following types:
- cv2.BORDER_CONSTANT - Adds a constant colored border. The value should be given as next argument.
- cv2.BORDER_REFLECT - Border will be mirror reflection of the border elements, like this : fedcba|abcdefgh|hgfedcb
- cv2.BORDER_REFLECT_101 or cv2.BORDER_DEFAULT - Same as above, but with a slight change, like this : gfedcb|abcdefgh|gfedcba
- cv2.BORDER_REPLICATE - Last element is replicated throughout, like this: aaaaaa|abcdefgh|hhhhhhh
- cv2.BORDER_WRAP - Can’t explain, it will look like this : cdefgh|abcdefgh|abcdefg
- value - Color of border if border type is cv2.BORDER_CONSTANT
import cv2import numpy as npfrom matplotlib import pyplot as pltBLUE = [255,0,0]img1 = cv2.imread('opencv_logo.png')replicate = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REPLICATE)reflect = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT)reflect101 = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT_101)wrap = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_WRAP)constant= cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_CONSTANT,value=BLUE)plt.subplot(231),plt.imshow(img1,'gray'),plt.title('ORIGINAL')plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('REPLICATE')plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('REFLECT')plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('REFLECT_101')plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP')plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
以上操作后画出的边框示例如下:
图像的数学操作
主要学习
cv2.add(), cv2.addWeighted()
两个函数
图像叠加
numpy相加为取模计算
opecv的add函数为饱和计算
>>> x = np.uint8([250])>>> y = np.uint8([10])>>> print cv2.add(x,y) # 250+10 = 260 => 255[[255]]>>> print x+y # 250+10 = 260 % 256 = 4[4]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
图像融合
图像的融合公式:g(x) = (1-a)f0(x) + af1(x);a的取值范围是0—1;
cv2.addWeighted()函数的图像融合:g(x) = (1-a)f0(x) + af1(x) + b
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.destroyAllWindows()
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
融合图像示例:
图像位操作
图像位操作主要包括:AND、OR、 NOT、 XOR
# Load two imagesimg1 = cv2.imread('messi5.jpg')img2 = cv2.imread('opencv_logo.png')# I want to put logo on top-left corner, So I create a ROIrows,cols,channels = img2.shaperoi = img1[0:rows, 0:cols ]# Now create a mask of logo and create its inverse mask alsoimg2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)ret, mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY)mask_inv = cv2.bitwise_not(mask)# Now black-out the area of logo in ROIimg1_bg = cv2.bitwise_and(roi,roi,mask = mask_inv)# Take only region of logo from logo image.img2_fg = cv2.bitwise_and(img2,img2,mask = mask)# Put logo in ROI and modify the main imagedst = cv2.add(img1_bg,img2_fg)img1[0:rows, 0:cols ] = dstcv2.imshow('res',img1)cv2.waitKey(0)cv2.destroyAllWindows()
- 1
- 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
- 1
- 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
位操作后图像示例:
Python OpenCV代码检测与速度优化
- cv2.getTickCount:获得当前的时钟tick数
- cv2.getTickFrequency:获得时钟频率,即每秒的tick数
img1 = cv2.imread('messi5.jpg')e1 = cv2.getTickCount()for i in xrange(5,49,2): img1 = cv2.medianBlur(img1,i)e2 = cv2.getTickCount()t = (e2 - e1)/cv2.getTickFrequency()print t# Result I got is 0.521107655 seconds
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
cv2.useOptimized():检测是否开启优化
cv2.setUseOptimized():设置是否优化
# check if optimization is enabledIn [5]: cv2.useOptimized()Out[5]: TrueIn [6]: %timeit res = cv2.medianBlur(img,49)10 loops, best of 3: 34.9 ms per loop# Disable itIn [7]: cv2.setUseOptimized(False)In [8]: cv2.useOptimized()Out[8]: FalseIn [9]: %timeit res = cv2.medianBlur(img,49)10 loops, best of 3: 64.1 ms per loop
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
本篇比较麻烦的就是位操作了,分析好久,还没完全弄明白;有待更新。