为了从dan哥获取答案,在答题卡中找到答案的位置,所以有了本篇openCV的学习笔记。记录遇到的坑和解决方法。
前置
目前openCV已经到了2.0版本,据说语法简单了很多,所以我们就用这个版本。
import cv2
因为图片是由一个个像素点组成,而像素点又是rgb值来表示,所以图片在python中就是一堆rgb值。
恰好Numpy可以很好的处理这堆像素点,所以还要
import numpy as np
打开图像
打开图片一句话搞定:1
img = cv2.imread(r'img\\img.png')
显示图像需要几个步骤▼1
2
3
4
5def display_im(img):
cv2.namedWindow("Image", cv2.WINDOW_NORMAL) # 创建图像窗口,默认cv2.WINDOW_AUTOSIZE,不可调窗口大小。cv2.WINDOW_NORMAL可调节大小。
cv2.imshow("Image", img) # 显示指定图像
cv2.waitKey (0) # 暂停并等待键盘输入;0表示你不输入它就一直等。不等的话图片一闪就过去了,啥都看不到)
cv2.destroyAllWindows() # #释放窗口,简单暴力释放掉所有的窗口
查看图像大小
一句话~1
print(img.shape[:2])
输出结果是(38, 80)
,记好了一会还会提到这个数。
保存图像
同样是一句话搞定1
cv2.imwrite('target.png', img)
处理图像(基础版)
python中的图像
比如这张简单的图像
用cv2打开,然后直接打印出来▼1
2img = cv2.imread(r'img.png')
print(img)
结果是这样的一坨数组,为了方便观察,我这里手动转换一下。
- 数据量比较大,只显示了首尾的内容
- 图片四角都是白色的,所以这里只能看到255
- 通过
np.set_printoptions(threshold=np.inf)
可以打印所有值
1 | [[[255 255 255] |
这样看起来好多了▼1
2
3
4
5
6
7[
[[255 255 255] [255 255 255] [255 255 255] ..., [255 255 255] [255 255 255] [255 255 255]]
[[255 255 255] [255 255 255] [255 255 255] ..., [255 255 255] [255 255 255] [255 255 255]]
...,
[[255 255 255] [255 255 255] [255 255 255] ..., [255 255 255] [255 255 255] [255 255 255]]
[[255 255 255] [255 255 255] [255 255 255] ..., [255 255 255] [255 255 255] [255 255 255]]
]
让洒家来简单分析一下这个数组吧▼1
2
3
4print(len(img)) #告诉洒家你这个数组一共有几行?
print(len(img[0])) # 第一行有几列?
print(len(img[0][0])) # 第一列有几个元素?
print(len(img[0][0][0]))# 第一个元素里有几个东西?
结果如下▼1
2
3
4
538
80
3
---------------------------------------------------------------------------
TypeError
数组有38行80列,眼不眼熟?和上面的(38, 80)
对上了!所以▼
3
是什么?是[255 255 255]
,熟悉RGB
的都知道是红绿蓝3种颜色的值。然而CV里是BGR
,不要搞混哟。图片是由一行一行的彩色像素点组成的,所以我们可以用一个三维数组来表示图片中的每一个点。- 最里面的数组
[255 255 255]
是一个BGR
表示的像素点颜色 - 一行
[[255 255 255] ..., [255 255 255]]
就表示图片的一行像素点,一行有80个这样的点 - 所有行放在一起一共38行,就是一副完整的图片了。这也是为什么我们可以用numpy来处理图片了。
最后的TypeError
是什么鬼? - 图片的最小单位就是像素里的三个颜色。颜色是个数值而不是数组,对数值用
len()
就报错了。
转换成灰度图像
灰度图像有助提升复杂操作的速度哦~
还是一句话:1
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
来看一下结果,红字变成灰字了。1
2
3
4
5
6
7[[255 255 255 ..., 255 255 255]
[255 255 255 ..., 255 255 255]
[255 255 255 ..., 255 255 255]
...,
[255 255 255 ..., 255 255 255]
[255 255 255 ..., 255 255 255]
[255 255 255 ..., 255 255 255]]
- 可以看到由3维数组变成了2位数组(啊,受到了降维攻击!)。
- 这是因为灰度图像的像素点只有一种颜色,用0到255的值就能表示了。
uint8
(无符号整形变量)的范围正好是0-255,所以numpy处理图像通常都用这个格式。- 这里打印依然是图像的四个角,所以还是255.。。。
截取图像
借助python的切片器可以很优雅的截取像素,洒家截一块不是纯白的给你们看看▼1
img_cut = img[10:30, 30:40] # 截取high,width
截取第11到29行,30到40列。总算有些不一样值出现了▼1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20[[255 255 255 255 255 250 234 255 255 255]
[255 255 255 255 255 184 128 223 255 255]
[255 255 255 255 255 239 147 128 231 255]
[255 255 255 255 255 255 243 144 223 255]
[255 255 255 255 255 255 255 250 255 250]
[255 255 255 255 255 255 255 255 255 250]
[255 255 255 255 252 221 221 221 240 213]
[255 255 255 255 246 120 120 120 205 200]
[255 255 255 255 255 252 252 126 205 255]
[255 255 255 255 255 255 255 126 205 255]
[255 255 255 255 255 255 255 126 205 255]
[255 255 255 255 255 255 255 126 205 255]
[255 255 255 255 255 255 255 126 205 208]
[255 255 255 255 255 255 253 125 186 242]
[255 255 255 255 252 200 140 174 166 128]
[255 255 255 255 255 172 179 254 255 226]
[255 255 255 255 255 248 254 255 255 255]
[255 255 255 255 255 255 255 255 255 255]
[255 255 255 255 255 255 255 255 255 255]
[255 255 255 255 255 255 255 255 255 255]]
处理图像(高级版)
给你们来点高级货~
搜索图像
先上代码▼1
res = cv2.matchTemplate(target, img, cv2.TM_CCOEFF_NORMED)
意思就是从target
图片中找到img
图片,找到后给出一个。。。。
偶,时间不早了,下次接着写吧~