报错:[ WARN:0@0.127] global loadsave.cpp:268 cv::findDecoder imread_('D:\学习计划\ai\深度学习_图像识别原理\stage3\flower_data_little\train\tulips\16702188449_3dacce90b2_m.jpg'): can't open/read file: check file path/integrity
图片存在但报错,初步推断是歧义问题 ,存在\t 等特殊符
发现是OpenCV 的 imread 在 Windows 上对非 ASCII 路径(如中文)兼容性差 ,经常静默失败(不报错,只返回 None)
import os
import sys
import json
from hmac import digest_size
# 导入matplotlib库
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
from torchvision import transforms, datasets
import torch.optim as optim
from tqdm import tqdm
# cv2导入
import cv2
# 判断cpu还是gpu
device = torch.device('cuda' if torch.cuda.is_available() else "cpu")
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
DATA_PATH = "D:\\学习计划\\ai\\深度学习_图像识别原理\\stage3\\flower_data_little\\train"
# 显示样本图片
def display_sample_images():
print("xxxx")
fig, axes = plt.subplots(3, 3, figsize=(10, 10))
i = 0
"""
top 起始目录路径(字符串),遍历从这里开始
topdown=True 默认为 True:先访问父目录,再进入子目录
若为 False:先访问最深层子目录,再回溯到父目录
οnerrοr=None 可选回调函数,当发生 OSError(如权限不足)时调用
例如:οnerrοr=lambda e: print(f"Error: {e}")
followlinks=False 是否跟随符号链接(软链接)
默认 False(避免循环引用或无限递归)
return _walk(fspath(top), topdown, onerror, followlinks)
(root, dirs, files)
top, dirs, nondirs
"""
for root, _, files in os.walk(DATA_PATH):
print(root)
for file in files:
if i >= 9: # 限制最多显示9张图片
break
if file.lower().endswith(('.png', '.jpg', '.jpeg')):
image_path = os.path.join(root, file)
img = cv2.imread(image_path)
if img is not None:
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 转换为RGB颜色
ax = axes.flatten()[i] # 获取对应的子图
ax.imshow(img)
ax.set_title(f'Image{i + 1}')
ax.axis('off') # 不显示坐标轴
plt.show()
if __name__ == '__main__':
display_sample_images()
✅ 错误总结
主要遇到的问题是 OpenCV 的 cv2.imread() 函数无法正确读取位于含有中文字符路径下的图片文件。具体原因如下:
1. 路径转义问题
- 使用了双反斜杠
\分隔目录,虽然避免了部分转义问题,但路径中的某些字符组合(如\12_...)仍可能被误认为转义序列。
2. OpenCV 对非 ASCII 路径支持不佳
- OpenCV 的
imread方法对包含中文或其他非 ASCII 字符的路径支持较差,在 Windows 环境下尤其明显,可能会静默返回None。
3. 缺乏错误处理机制
- 原始代码没有检查
cv2.imread()的返回值是否为None,也没有适当的异常处理,导致难以快速定位问题所在。
✅ 错误排查与解决方案
🔍 排查步骤
1. 验证路径格式
- 检查路径字符串是否使用了原始字符串
r"..."或正斜杠/来避免转义字符问题。
2. 测试路径访问性
- 手动确认路径是否存在且文件可读(例如通过双击打开图片)。
3. 添加错误日志
-
在尝试读取每张图片后打印相关信息,以确定哪些文件未能成功加载:
if img is None: print(f"无法读取图片: {image_path}")
4. 替换图片读取方法
- 鉴于 OpenCV 对非 ASCII 路径的支持限制,考虑使用 PIL(Pillow)库来替代 OpenCV 进行图片读取,因为 PIL 更好地支持各种编码路径。
🛠 解决方案
方案 A:使用 PIL 替代 OpenCV 读取图片
from PIL import Image
import numpy as np
# 使用 PIL 读取图片(支持中文路径)
pil_img = Image.open(image_path).convert('RGB')
img_array = np.array(pil_img) # 转为 NumPy 数组供 Matplotlib 显示
方案 B:如果必须使用 OpenCV,采用 cv2.imdecode 绕过路径限制
def cv_imread(file_path):
cv_img = cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), -1)
return cv_img
img = cv_imread(image_path)
if img is not None:
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
💡 推荐使用方案 A,因为它更简洁、稳定,并且兼容性更好。
✅ 完整优化后的示例代码
import os
import matplotlib.pyplot as plt
from PIL import Image # 使用 PIL 替代 cv2 读取图片
import numpy as np
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False # 正常显示负号
DATA_PATH = r"D:\学习计划\ai\深度学习_图像识别原理\stage3\flower_data_little\train"
def display_sample_images():
print("开始加载样本图片...")
fig, axes = plt.subplots(3, 3, figsize=(10, 10))
i = 0
for root, _, files in os.walk(DATA_PATH):
for file in files:
if i >= 9:
break
if file.lower().endswith(('.png', '.jpg', '.jpeg')):
image_path = os.path.join(root, file)
try:
pil_img = Image.open(image_path).convert('RGB') # 使用 PIL 读取
img_array = np.array(pil_img) # 转为 numpy array (H, W, C)
ax = axes.flatten()[i]
ax.imshow(img_array)
ax.set_title(f'Image{i + 1}')
ax.axis('off')
i += 1
except Exception as e:
print(f"跳过无法读取的文件: {image_path} | 错误: {e}")
continue
if i >= 9:
break
plt.tight_layout()
plt.show()
if __name__ == '__main__':
display_sample_images()
✅ 总结
- 根本原因 :OpenCV 的
imread对非 ASCII 路径支持不佳,尤其是在 Windows 系统上。 - 解决方案:改用 Pillow 库读取图片,绕过路径编码问题。
- 额外改进:增加异常捕获和日志输出,帮助更快定位问题。
