本质原因并非网上某些地方说的是中文编码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)

Logo

分享最新、最前沿的AI大模型技术,吸纳国内前几批AI大模型开发者

更多推荐