python opencv的imread方法无法读取图片问题
作者:ZXF-BW
python opencv的imread方法无法读取图片
读取的路径、文件名只能带有英文数字及一些特定字符,不能带有中文、日文等字符!!!
利用cv2.imread()读取文件夹中的四个图片文件:
读取’error副本.png’图片(文件名带有中文),结果为None,未能读取;
读取‘新建文件夹/error.png’图片(路径中带中文),结果为None,未能读取;
读取‘トニカクカワイイ.png’图片(文件名带日文),结果为None,未能读取;
而文件名改为英文时得到’numpy.ndarray’类型,说明成功读取。
再看展示图片操作:
用cv2.imshow(‘错误’, d)显示图片时,将标题设为’错误‘,但弹窗标题显示为乱码,说明是编码错误。
总结原因:
是字符编码的问题,导致cv2.imread未能找到对应图片文件。
目前找到的解决方法是修改路径和文件名为英文数字及部分特定字符。
python opencv imread()中文路径返回为空None的解决(imdecode函数的使用)
本质原因并非网上某些地方说的是中文编码UNICODE、UTF-8之类的问题,其实是python版opencv不接受NON-ASCII的中文路径,为了使用中文路径,可以借助一些其他的库。
首先介绍一种通过numpy库(毕竟这个是python中几乎最常用库之一了)的方法。
借助Numpy库
读取图像时,借助numpy库的fromfile函数先把图像文件以数据的方式读入内存,然后在内存缓冲区内用opencv提供的imdecode函数将该数据解码成图像数据,
核心代码如下:
path = r"D:\Learn4Python\中文路径\中文文件名.jpg" dat = np.fromfile(path,dtype=np.uint8) img = cv2.imdecode(dat,cv2.IMREAD_UNCHANGED)
写入(保存)图像时,用opencv提供的imencode函数将图像数据编码成numpy的数据,然后借助numpy的tofile函数把数据写入到路径文件,
核心代码如下:
path_zh_write = r"D:\Learn4Python\中文路径\中文文件名写入图像.jpg" out = cv2.imencode(".jpg",img) out[1].tofile(path_zh_write)
为了方便学习和完整理解,写了一段实验代码供大家参考
完整代码如下
import cv2 import numpy as np #试验四种情况:路径无中文、仅文件名中文、目录和文件名均有中文、仅目录有中文 path1 = r"D:\Learn4Python\EnglishFileName.jpg" path2 = r"D:\Learn4Python\中文文件名.jpg" path3 = r"D:\Learn4Python\中文路径\中文文件名.jpg" path4 = r"D:\Learn4Python\中文路径\EnglishFileName.jpg" path_zh_write = r"D:\Learn4Python\中文路径\中文文件名写入图像.jpg" path_en_write = r"D:\Learn4Python\EnglishFileName_writeImg.jpg" img1 = cv2.imread(r"D:\Learn4Python\EnglishFileName.jpg") img2 = cv2.imread(r"D:\Learn4Python\中文文件名.jpg") img3 = cv2.imread(r"D:\Learn4Python\中文路径\中文文件名.jpg") img4 = cv2.imread(r"D:\Learn4Python\中文路径\EnglishFileName.jpg") #检查读取情况,结果只有路径无中文的情况读取成功 if img1 is None: print("img1 imread failed.") else: print("img1 imread ok:",img1.shape) if img2 is None: print("img2 imread failed.") else: print("img2 imread ok:",img2.shape) if img3 is None: print("img3 imread failed.") else: print("img3 imread ok:",img3.shape) if img4 is None: print("img4 imread failed.") else: print("img4 imread ok:",img4.shape) #借助numpy读取图像 dat1 = np.fromfile(path1,dtype=np.uint8) img_d1 = cv2.imdecode(dat1,cv2.IMREAD_UNCHANGED) dat2 = np.fromfile(path2,dtype=np.uint8) img_d2 = cv2.imdecode(dat2,cv2.IMREAD_UNCHANGED) dat3 = np.fromfile(path3,dtype=np.uint8) img_d3 = cv2.imdecode(dat3,cv2.IMREAD_UNCHANGED) dat4 = np.fromfile(path4,dtype=np.uint8) img_d4 = cv2.imdecode(dat4,cv2.IMREAD_UNCHANGED) #结果全部读取成功 if img_d1 is None: print("img_d1 imdecode failed.") else: print("img_d1 imdecode ok:",img_d1.shape) if img_d2 is None: print("img_d2 imdecode failed.") else: print("img_d2 imdecode ok:",img_d2.shape) if img_d3 is None: print("img_d3 imdecode failed.") else: print("img_d3 imdecode ok:",img_d3.shape) if img_d4 is None: print("img_d4 imdecode failed.") else: print("img_d4 imdecode ok:",img_d4.shape) #尝试用imwrite将图像写入文件, #结果:无中文的路径写入成功,含中文的路径写入失败 if cv2.imwrite(path_en_write,img1): print("english path writing is ok!(use imwrite)") else: print("english path writing is failed.(use imwrite)") if cv2.imwrite(path_zh_write,img1): print("chinese path writing is ok!(use imwrite)") else: print("chinese path writing is failed.(use imwrite)") #借助numpy将图像写入含中文路径的文件,结果成功 out = cv2.imencode(".jpg",img1) out[1].tofile(path_zh_write) try: f = open(path_zh_write) f.close() print("chinese path writing is ok!(use imencode and tofile)") except: print("chinese path writing is failed.(use imencode and tofile)")
以上代码运行结果如下:
img1 imread ok: (129, 186, 3)
img2 imread failed.
img3 imread failed.
img4 imread failed.
img_d1 imdecode ok: (129, 186, 3)
img_d2 imdecode ok: (129, 186, 3)
img_d3 imdecode ok: (129, 186, 3)
img_d4 imdecode ok: (129, 186, 3)
english path writing is ok!(use imwrite)
chinese path writing is failed.(use imwrite)
chinese path writing is ok!(use imencode and tofile)
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。