OpenCV 4计算机视觉:Python语言实现(原书第3版)
上QQ阅读APP看书,第一时间看更新

2.2.1 读取/写入图像文件

OpenCV提供了imread函数来从文件加载图像,也提供了imwrite函数来将图像写入文件。这些函数支持静态图像(非视频)的各种文件格式。支持的格式各不相同——在OpenCV的自定义构建中可以添加或删除某些格式——但是,通常BMP、PNG、JPEG和TIFF都是所支持的格式。

我们来研究一下在OpenCV和NumPy中图像表示的解剖结构。一幅图像就是一个多维数组,有列像素和行像素,每个像素都有一个值。对于不同类型的图像数据,像素值可以使用不同的格式。例如,通过简单地创建一个二维NumPy数组,可以从头开始创建一幅3×3的黑色正方形图像:

如果将这幅图像打印到控制台,获得的结果如下所示:

这里,每个像素都用一个8位整数表示,这意味着每个像素的值都在0~255的范围内,其中0表示黑色,255表示白色,中间的值表示灰色。这是一幅灰度图像。

现在,我们使用cv2.cvtColor函数把这幅图像转换成蓝–绿–红(Blue-Green-Red,BGR)格式:

我们来看图像是如何变化的:

如你所见,现在每个像素都用一个三元数组表示,每个整数分别表示三个颜色通道(B、G和R)中的一个。HSV之类的其他常见颜色模型的表示方法也类似,只是取值范围不同。例如,HSV颜色模型的色调值的范围是0~180。

有关颜色模型的更多内容,请参阅第3章,尤其是3.2节。

通过查看shape属性,你可以查看图像的结构,shape属性返回行、列和通道数(如果有多个通道的话)。

考虑如下示例:

上述代码将打印(5,3),表示我们有一幅5行3列的灰度图像。如果将该图像转换成BGR格式,shape将是(5,3,3),表示每个像素有3个通道。

图像可以从一种文件格式加载并保存为另一种格式。例如,把一幅图像从PNG转换为JPEG:

OpenCV的Python模块命名为cv2,尽管我们使用的是OpenCV 4.x而非OpenCV 2.x。以前,OpenCV有两个Python模块:cv2和cv。cv封装了用C实现的OpenCV的一个旧版本。目前,OpenCV只有cv2 Python模块,该模块封装了用C++实现的OpenCV当前版本。

默认情况下,imread返回BGR格式的图像,即使该文件使用的是灰度格式。BGR表示与红–绿–蓝(Red-Green-Blue,RGB)相同的颜色模型,只是字节顺序相反。

我们还可以指定imread的模式,所支持的选项包括:

·cv2.IMREAD_COLOR:该模式是默认选项,提供3通道的BGR图像,每个通道一个8位值(0~255)。

·cv2.IMREAD_GRAYSCALE:该模式提供8位灰度图像。

·cv2.IMREAD_ANYCOLOR:该模式提供每个通道8位的BGR图像或者8位灰度图像,具体取决于文件中的元数据。

·cv2.IMREAD_UNCHANGED:该模式读取所有的图像数据,包括作为第4通道的α或透明度通道(如果有的话)。

·cv2.IMREAD_ANYDEPTH:该模式加载原始位深度的灰度图像。例如,如果文件以这种格式表示一幅图像,那么它提供每个通道16位的一幅灰度图像。

·cv2.IMREAD_ANYDEPTH|cv2.IMREAD_COLOR:该组合模式加载原始位深度的BGR彩色图像。

·cv2.IMREAD_REDUCED_GRAYSCALE_2:该模式加载的灰度图像的分辨率是原始分辨率的1/2。例如,如果文件包括一幅640×480的图像,那么它加载的是一幅320×240的图像。

·cv2.IMREAD_REDUCED_COLOR_2:该模式加载每个通道8位的BGR彩色图像,分辨率是原始图像的1/2。

·cv2.IMREAD_REDUCED_GRAYSCALE_4:该模式加载灰度图像,分辨率是原始图像的1/4。

·cv2.IMREAD_REDUCED_COLOR_4:该模式加载每个通道8位的彩色图像,分辨率是原始图像的1/4。

·cv2.IMREAD_REDUCED_GRAYSCALE_8:该模式加载灰度图像,分辨率是原始图像的1/8。

·cv2.IMREAD_REDUCED_COLOR_8:该模式加载每个通道8位的彩色图像,分辨率为原始图像的1/8。

举个例子,我们将一个PNG文件加载为灰度图像(在此过程中会丢失所有颜色信息),再将其保存为一个灰度PNG图像:

除非是绝对路径,否则图像的路径都是相对于工作目录(Python脚本的运行路径)的,因此在前面的例子中,MyPic.png必须在工作目录中,否则将找不到该图像。如果你希望避免对工作目录的假设,可以使用绝对路径,比如Windows上的C:\Users\Joe\Pictures\MyPic.png、Mac上的/Users/Joe/Pictures/MyPic.png,或者Linux上的/home/joe/pictures/MyPic.png。

imwrite()函数要求图像为BGR格式或者灰度格式,每个通道具有输出格式可以支持的特定位数。例如,BMP文件格式要求每个通道8位,而PNG允许每个通道8位或16位。