OpenCV imread()和imdecode():读取图像文件(附带实例)
OpenCV 中的 imread() 函数用于读取图像文件或加载图像文件,其声明如下:
如果从指定文件加载图像成功,就返回一个存储着图片像素数据的矩阵。如果无法读取图像(缺少文件、权限不正确、格式不受支持或无效),那么函数将返回空。
在 Windows 操作系统下,OpenCV 的 imread() 函数支持如下类型的图像载入:
如果文件读取失败,就返回 None。可以通过返回值是否为 None 来判断是否读取正确,比如:
值得注意的是,函数 imread() 根据内容而不是文件扩展名来确定图像的类型,比如把某个 BMP 图像文件的后缀名改为 JPG,imread() 依然能探测到这个文件是 BMP 图像文件。
另外,imread() 的第一个参数一般是图像文件的绝对路径或相对路径。对于绝对路径,imread() 除了不支持单右斜线(\)形式,其他斜线形式都支持,比如双右斜线形式(\\)、双左斜线形式(//)、单左斜线形式(/)等。通常相对路径更加方便点,只要把图像文件放在工程目录下即可。
注意,imread() 的文件路径不支持中文路径,如果要支持中文路径,可以用函数 imdecode()。该函数从指定的内存缓存中读取一幅图像,其声明如下:
如果内存缓冲区太短或包含无效数据,就返回空矩阵图像。实际上,imread() 和 imdecode() 内部都是通过 ImageDecoder 类来进行图像解码的。
例如,下列代码从文件中读取数据到内存:
【实例 1】多种路径读取图像文件。
运行工程,结果如下图所示:
在用 imread() 或 imdecode() 加载图像文件时,可以指定模式来获得不同的效果。
【实例 2】用不同模式打开图像文件。
保存工程并运行,第一幅图像运行结果如下图所示。然后按空格键,可以继续显示下一幅图像。
cv.imread(filename[, flags]) -> retval参数 filename 表示要读取的图像文件名;flags 表示读取模式,取值如下:
- cv.IMREAD_ANYDEPTH:其值是 2,取这个标志的话,若载入的图像深度为 16 位或者 32 位,则返回对应深度的图像,否则转换为 8 位图像再返回;
- cv.IMREAD_COLOR:其值是 1,取这个标志的话,图像转为彩色图像(BGR,3 通道);
- cv.IMREAD_GRAYSCALE:其值是 0,取这个标志的话,始终将图像转换成灰度图,即返回灰度图像,1 通道;
- cv. IMREAD_UNCHANGED,其值是 −1,表示载入原图。
如果从指定文件加载图像成功,就返回一个存储着图片像素数据的矩阵。如果无法读取图像(缺少文件、权限不正确、格式不受支持或无效),那么函数将返回空。
在 Windows 操作系统下,OpenCV 的 imread() 函数支持如下类型的图像载入:
- JPEG 文件:*.jpeg、*.jpg、*.jpe;
- JPEG 2000 文件:*.jp2;
- PNG 文件:*.png;
- 便携文件格式:*.pbm、*.pgm、*.pp;
- Sun rasters 光栅文件:*.sr、*.ras;
- TIFF 文件:*.tiff、*.tif;
- Windows 位图:*.bmp、*.dib。
如果文件读取失败,就返回 None。可以通过返回值是否为 None 来判断是否读取正确,比如:
img = cv.imread("p1.jpg"); #读取第一幅图片 if img is None: sys.exit("Could not read the p1.jpg.") #如果读取为空,则退出程序img 实际上是一个 NumPy 的 array 数组,包含了每个像素点的数据(如果是彩色模式,就是BGR值,如果是灰度模式,则是灰度值)。我们可以通过下标访问每一个像素点的数据,对每一个像素点进行更改操作。
值得注意的是,函数 imread() 根据内容而不是文件扩展名来确定图像的类型,比如把某个 BMP 图像文件的后缀名改为 JPG,imread() 依然能探测到这个文件是 BMP 图像文件。
另外,imread() 的第一个参数一般是图像文件的绝对路径或相对路径。对于绝对路径,imread() 除了不支持单右斜线(\)形式,其他斜线形式都支持,比如双右斜线形式(\\)、双左斜线形式(//)、单左斜线形式(/)等。通常相对路径更加方便点,只要把图像文件放在工程目录下即可。
注意,imread() 的文件路径不支持中文路径,如果要支持中文路径,可以用函数 imdecode()。该函数从指定的内存缓存中读取一幅图像,其声明如下:
cv.imdecode(buf, flags) -> retval
- buf 是存放图像数据的内存缓存,通常用字节数组或向量的形式表示;
- flags 的含义同 imread() 函数的 flags 参数。
如果内存缓冲区太短或包含无效数据,就返回空矩阵图像。实际上,imread() 和 imdecode() 内部都是通过 ImageDecoder 类来进行图像解码的。
例如,下列代码从文件中读取数据到内存:
import numpy as np #导入numpy模块 img = cv.imdecode(np.fromfile(imgpath,dtype=np.uint8),-1)其中,fromfile() 函数是支持中文路径的,它通过读取文件在内存中构造数组数据,这样 imdecode 就能在内存中获得数组数据了,继而进行解码。
【实例 1】多种路径读取图像文件。
import cv2 as cv import numpy as np #导入numpy模块 #imgpath = "d:\\我的图片\\p1.jpg"; #imgpath = "d://test//p1.jpg"; #imgpath = "d:/test/p1.jpg" #imgpath = "d:/test//test2\\test3//test4//p1.jpg";#-- 4 --以上三种混合法 imgpath = "p1.jpg"; #-- 5 --相对路径法,放在和test.py同一路径 img = cv.imdecode(np.fromfile(imgpath,dtype=np.uint8),-1) cv.imshow("img",img) #显示窗口 cv.waitKey(0) #等待按键 cv.destroyAllWindows() #释放窗口我们对上面的 6 种路径进行了测试,任何一种都是支持的,都可以成功读取并显示图片。其中较常用的是相对路径,也就是第 5 种。图片放在和 3.1.py 文件同一路径下,既可以在 PyCharm 中直接运行来打开图片,也可以到命令行窗口下执行“pthon 3.1.py”命令来打开图片。
运行工程,结果如下图所示:

在用 imread() 或 imdecode() 加载图像文件时,可以指定模式来获得不同的效果。
【实例 2】用不同模式打开图像文件。
import cv2 as cv import numpy as np #导入numpy模块 imgpath = "p1.jpg"; img = cv.imread(imgpath,cv.IMREAD_ANYDEPTH) cv.imshow("img",img) #显示窗口 cv.waitKey(0) #等待按键 img = cv.imread(imgpath,cv.IMREAD_COLOR) cv.imshow("img",img) #显示窗口 cv.waitKey(0) #等待按键继续下一幅 img = cv.imread(imgpath,cv.IMREAD_GRAYSCALE) cv.imshow("img",img) #显示窗口 cv.waitKey(0) #等待按键 cv.destroyAllWindows() #释放窗口我们用 3 种模式来加载图片:
- 对于 cv.IMREAD_ANYDEPTH,由于 p1.jpg 的位深度是 24(不是 16 或 32),因此会转换为 8 位图像;
- cv.IMREAD_COLOR 会将图像以彩色方式加载,由于我们的图像本来就是彩色图像,因此没有变化;
- cv.IMREAD_GRAYSCALE 会将图像转换成灰度图,所以加载后图像是黑白的。
保存工程并运行,第一幅图像运行结果如下图所示。然后按空格键,可以继续显示下一幅图像。
