小强学Python+OpenCV之-1.1图像加载、显示、保存

小强学Python+OpenCV之-1.1图像加载、显示、保存

目标

你将学会怎样
1. 从硬盘读取一幅图像
2. 将图像显示出来
3. 保存一幅图像到硬盘

一、体验

下面,我们先直接看一段代码:image_pro.py

# 导入OpenCV库
import cv2

# 加载一幅图像
image = cv2.imread("flower.jpg")
# 显示图像
cv2.imshow("Image", image)
# 等待输入
cv2.waitKey(0)

执行该脚本:python image_pro.py
我们会看到输出:
小强学Python+OpenCV之-1.1图像加载、显示、保存_第1张图片

二、分析

在上面的代码中,

1.导入库

首先要导入opencv库。这是我们必须要用到的库,所以要先导入。

# 导入OpenCV库
import cv2

2.加载图像

图像的加载使用cv2.imread函数(瞧,我们用到了来自cv2的函数,所以前面的导入是必须的),函数参数为图像文件的路径。函数返回一个numpy数组。PS.这里简单提一下,NumPy 是一个基础科学的计算库,可以完成矩阵运算等。

# 加载一幅图像
image = cv2.imread("flower.jpg")

3.显示图像

图像的显示使用cv2.imshow函数。该函数会创建一个窗口,并在此窗口中显示用numpy数组表示的图像。所以,函数的参数为:第一个,窗口的名称;第二个,用numpy数组表示的图像

# 显示图像
cv2.imshow("Image", image)

在cv2库中。我们可以waitKey函数来通过等待来自键盘的输入而使用程序暂停一段时间,如果该函数的参数是0,表示将无限期等待来自键盘的输入事件,若接收到来自键盘的事件则退出。非0,表示等等若干毫秒后,若还是没有来自键盘的输入事件,则退出。

# 等待输入
cv2.waitKey(0)

4.疑点

4.1 numpy是什么

或许我们对于上面cv2.imread函数的返回值numpy数组有疑问。这里,我们可以将该数组打印出来,看一下,到底是怎么回事。在cv2.imshow函数之前,增加如下一行代码:

print image

我们会看到诸如下面的输出:

[[[ 5 38  3]
  [ 5 38  3]
  [ 6 39  4]
  ..., 
  [39 71 36]
  [38 72 32]
  [38 72 32]]

 [[ 8 41  6]
  [ 8 41  6]
  [ 8 41  6]
  ..., 
  [35 67 32]
  [35 68 31]
  [35 69 29]]

 [[12 45 10]
  [12 45 10]
  [12 45 10]
  ..., 
  [30 59 26]
  [31 62 25]
  [32 63 24]]

 ..., 
 [[ 8 20  0]
  [12 24  2]
  [15 28  6]
  ..., 
  [ 3 34  7]
  [ 3 34  7]
  [ 3 34  7]]

 [[10 22  0]
  [12 24  2]
  [14 27  5]
  ..., 
  [ 0 27  2]
  [ 0 27  2]
  [ 0 28  3]]

 [[10 22  0]
  [12 24  2]
  [14 27  5]
  ..., 
  [ 0 27  2]
  [ 0 27  2]
  [ 0 28  3]]]

从这里,我们可以看到,这是一个三维数组。哦~原来图像是三维数组啊。是不是很简单?(且慢,后面会表示,有可以还是二维数组)

4.2 numpy有多大

那么,这个三维数组到底多大呢?
其实,我们可以使用numpy的shape函数来获取各个维度的长度。
在cv2.imread函数后增加如下几行代码:

print "height: %d pixels" % (image.shape[0])
print "width: %d pixels" % (image.shape[1])
print "channels: %d" % (image.shape[2])

得到结果如下:

height: 106 pixels
width: 159 pixels
channels: 3

这表示flower.jpg这幅图像的高度是106个像素,宽度159像素,3个通道(后面我们会知道3通道表示彩色图像)。

5.优化

上面的代码中有一个缺点:图像路径是手工编码,要想显示另一幅图像,还要修改代码。这是不可行的。我们改造如下:

# 导入OpenCV库
import cv2
# 导入参数解析库
import argparse

# 创建一个参数解析器
ap = argparse.ArgumentParser()
# 增加一个参数项--image,或简写-i
ap.add_argument("-i", "--image", required=True, help="Path to the image")
# 得到参数字典,vars是python核心函数,返回一个字典类型
args = vars(ap.parse_args())

# 加载一幅图像
image = cv2.imread(args["image"])
print "height: %d pixels" % (image.shape[0])
print "width: %d pixels" % (image.shape[1])
print "channels: %d" % (image.shape[2])
# 显示图像
cv2.imshow("Image", image)
# 另存图像
cv2.imwrite("saveAs.jpg", image)
# 等待输入
cv2.waitKey(0)

上面的代码中,我们做了两处修改:
1. 我们增加了一个参数解析器。这样的好处是,我们执行该脚本时,可以这样:

python image_pro.py --image flower.jpg

flower.jpg可以替换成任意你想显示的图像路径。
2. 最后,我们使用cv2.imwrite函数将flower.jpg另存成了saveAs.jpg。两个参数,一个是图像要保存的路径,一个是要保存的图像(numpy数组)。

总结

  1. 加载图像cv2.imread;显示图像cv2.imshow;保存图像cv2.imwrite。
  2. cv2.waitkey等等时长为毫秒,0表示无限等待。
  3. 图像表示为numpy数组形式。
  4. 参数解析器的使用。

你可能感兴趣的:(python+opencv,python-opencv)