opencv-图像的显示与存储
一、python-opencv的安装
方法一:使用pip命令
- opencv依赖于Numpy和wheel两个包,需要提前安装
- 若下载很慢可以使用 -i 设置使用清华源镜像
- opencv-python为基础包,opencv-contrib-python则包含额外的模块
pip install wheel
pip install numpy
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-contrib-python
方法二:去官网下载安装包,后手动安装
下载链接: https://sourceforge.net/projects/opencvlibrary/files/
二、图像的读取、显示与保存
图像读取
使用函数 cv2.imread()
读入图像,该函数包含两个参数
- 第一个参数以字符串形式提供图像的路径,可以是相对该程序的相对路径,或绝对路径
- 第二个参数表示如何读取这幅图片,如下为常用的flag
-
cv2.IMREAD_GRAYSCALE
:读入灰度模式图像,也可以用0
表示 -
cv2.IMREAD_COLOR
:读入彩色图像(不包含透明度),也可以用1
表示,为空缺时的默认参数 -
cv2.IMREAD_UNCHANGED
:读入一幅图像,并包括图像的alpha通道
注意: OpenCV 也不会提醒你路径是否错的,但是使用命令print img时得到的结果为None
# 引包
import numpy as np
import cv2
from matplotlib import pyplot as plt
# 读入图像
img = cv2.imread('image/01.png',0)
图像显示
方法一:使用Matplotlib显示图像
Matplotib是python的一个绘图库,其中包含各种各样的绘图方法,可以借助Matplotib编排、显示图像
这里使用plt.imshow()
的方法来显示图像,
- 该方法忽略了原图像的尺寸,其大小可以通过
plt.figure(figsize=(width, height))
手动设置 - 对于强制缩放的图像可以使用
interpolation = 'bicubic'
参数调整插值的方法以确保图像清晰 - 对于彩色图像,由于opencv的读取是按照BGR的顺序读入并存放数据,但matplotlib则以RGB的顺序显示,因而需要在显示时手动修改顺序,即
plt.imshow(img[,,::-1])
- 对于灰度图片,需要手动添加
cmap=gray
(0为黑色,255为白色) - 默认显示图片含有坐标轴标签,使用
plt.xticks([])
和plt.yticks([])
取消
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('image/01.jpg',1)
plt.imshow(img, cmap = 'gray', interpolation = 'bicubic')
plt.xticks([]), plt.yticks([])
plt.show()
方法二:使用opencv内置引擎
使用函数 cv2.imshow()
显示图像,返回结果为一个自动调整为图像大小的窗体
- 第一个参数是窗口的名字,多个窗口需给定不同的名字
- 第二个参数是需要展示的图像
- 该结果需要配合
cv2.waitKey(0)
和cv2.destroyAllWindows()
命令使窗口暂时停留 - 在服务器端没有安装X Serve,因而图片使用
cv2.imshow(img)
无法直接调用图形界面显示,可以直接使用Matplotlib来返回显示结果
img = cv2.imread('image/01.png',0)
cv2.show('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
图像的保存
使用cv2.imwrite()
方法保存图像,其第一个参数为保存文件的路径和命名(包括后缀和格式),第二个参数为需要保存的图像
cv2.imwrite('image/01.png',img)
三、颜色空间的转换与通道的拆合
颜色空间的概念与相互转换
颜色空间,是在某些标准下用通常可接受的方式对彩色加以说明的方式,常用的颜色空间有RGB、CMYK、HSV、EG
- RGB 颜色空间为加法混色,常用于彩色显示器上,图像包含3个通道(RGB),一个像素包含3个值,值的取值范围为[0, 255]
- CMYK颜色空间为减法混色,常用在印刷时,其数值越加越黑,每种颜色包含4个参数( 青色Cyan,洋红色Magenta,黄色Yellow,黑色Black)
- HSV颜色空间依据人类视觉概念,由3个要素组成(H/Hue:色调,颜色种类、S/Saturation:饱和度、V/Value:明度,颜色明亮度),一个像素有3个值,构成了一个圆锥形的空间
- CIE-XYZ颜色空间是人类颜色视觉的直接测定的颜色系统
opencv提供了 超过150中进行颜色空间转换的方法 , 使用cv2.cvtColor(input_image ,flag)
函数来进行转换,其中 flag就是转换类型 ,多使用如下两种flag:
- 对于BGR←→Gray的转换,可以使用
cv2.COLOR_BGR2GRAY
和COLOR_GRAY2RGB
- 对于BGR←→HSV的转换,我们用的flag就是
cv2.COLOR_BGR2HSV
和COLOR_HSV2BGR
官网教程额外提醒了, 不同的软件使用的值可能不同,所以当需要拿OpenCV的HSV值与其他软件的HSV值进行对比时,一定要记得归一化!
可以通过如下代码查看opencv所提供的全部与颜色转换相关的 flag:
import cv2
flags=[i for i in dir(cv2) if i.startswith('COLOR_')]
print(flags)
当然,这里的转化也可以手工操作,如RGB图像灰度化的常用公式为$ Gray=R0.3+G0.59+B*0.11$
图像的存储与像素值的提取
- RGB三通道图以三维矩阵的形式存储,其shape为[width,height,channel],注意channel的顺序为B、G、R
- 灰度单通道图以二位矩阵的形式存储,其shape为[width,height]
可以通过img.shape
参数查看图片的大小和通道数量(元组),img.size
获知像素的个数,img.dtype
每个像素的获知数据类型,即位深(一般为8位uint8,即2^8范围内)
import cv2
import numpy as np
img=cv2.imread('image/01.png')
print(img.shape)
print(img.size, img.dtype)
因而,可以直接使用Numpy结合下标访问或修改一张图片的某一像素值,甚至可以通过切片得到某一区域的图像
# 访问100,100位置处的颜色
px = img[100,100]
print(px)
>> [175 175 175]
# 访问100,100位置处B通道的值
blue = img[100,100,0]
print(blue)
>> 175
# 将100,100位置处的颜色修改为白色
img[100,100]=[255,255,255]
print(img[100,100])
>> [255 255 255]
如下操作是通过切片将图像上的区域复制到另一个位置上
import cv2
import numpy as np
from matplotlib import pyplot as plt
img=cv2.imread('image/01.jpg')
plt.figure(figsize=(14,5))
plt.subplot(121), plt.imshow(img[:,:,::-1]), plt.xticks([]), plt.yticks([])
hat=img[0:150,120:230]
img[0:150,300:410]=hat
plt.subplot(122), plt.imshow(img[:,:,::-1]), plt.xticks([]), plt.yticks([])
plt.show()
图像通道的拆合
有时我们需要对BGR三个通道分别进行操作,需要将其拆分成单个通道,有两种方法可以实现该目的
- 一种是利用Numpy的索引
b = img[:,:,:,0]
- 一种是利用
b,g,r = cv1.split(img)
相应的,也可以使用cv2.merge([b,g,r])
将三层通道合并
import cv2
import numpy as np
from matplotlib import pyplot as plt
fig=plt.figure(figsize=(15,5),dpi=80)
img=cv2.imread('image/01.jpg')
# 方法一(0--b, 1--g, 2--r)(imshow展示b通道)
plt.subplot(131);plt.imshow(img[:,:,0], cmap = 'gray', interpolation = 'bicubic')
plt.xticks([]), plt.yticks([])
# 方法二(展示g,r通道)
b,g,r=cv2.split(img)
plt.subplot(132);plt.imshow(g, cmap = 'gray', interpolation = 'bicubic')
plt.xticks([]), plt.yticks([])
plt.subplot(133);plt.imshow(r, cmap = 'gray', interpolation = 'bicubic')
plt.xticks([]), plt.yticks([])
plt.show()
提示:cv2.split()
是一个比较耗时的操作,若非必要尽可能使用Numpy 索引完成对图像的操作!
2020年2月23日 本性之初