将PNG图像转换为LMDB格式时脚本报错,如何成功运行?
解决PNG转LMDB脚本运行失败的方案
问题根源
报错显示libpng error: Read Error且AttributeError: 'NoneType' object has no attribute 'nbytes',本质是目标文件夹中的0868.png文件损坏/无法被OpenCV正常读取,同时原脚本没有添加读取失败的容错逻辑,直接访问None对象的属性导致崩溃。
具体修复步骤
1. 添加错误处理,跳过损坏文件
修改读取图片的循环代码,加入读取失败检查,跳过损坏文件并记录日志,避免程序崩溃:
print('Read images...') pbar = ProgressBar(len(img_list)) failed_files = [] # 记录读取失败的文件 dataset = [] data_size = 0 for i, v in enumerate(img_list): pbar.update('Read {}'.format(v)) img = cv2.imread(v, cv2.IMREAD_UNCHANGED) # 检查图片是否读取成功 if img is None: print(f"Warning: 无法读取文件 {v},已跳过") failed_files.append(v) continue dataset.append(img) data_size += img.nbytes # 打印读取失败的文件列表(可选) if failed_files: print(f"\n共跳过 {len(failed_files)} 个损坏文件:") for f in failed_files: print(f" - {f}")
2. 修复损坏的PNG文件(可选)
如果不想跳过0868.png,可以尝试修复该文件:
- 在Colab终端执行以下命令安装PNG修复工具并修复文件:
apt update && apt install -y pngcrush pngcrush -fix /content/drive/MyDrive/sub-dataset-2/divk/0868.png /content/drive/MyDrive/sub-dataset-2/divk/fixed_0868.png
- 修复完成后,替换原文件或修改
img_folder路径指向修复后的文件。
3. 优化内存占用(可选)
原脚本会将所有图片加载到内存中,图片数量多时会占用大量内存。可以改为读一张写一张,同时预计算总数据量:
# 预计算总数据量(跳过损坏文件) total_size = 0 failed_files = [] for v in img_list: img = cv2.imread(v, cv2.IMREAD_UNCHANGED) if img is None: failed_files.append(v) continue total_size += img.nbytes # 初始化LMDB env = lmdb.open(lmdb_save_path, map_size=total_size * 10) # 逐张读取并写入LMDB print('Write lmdb...') pbar = ProgressBar(len(img_list) - len(failed_files)) count = 0 with env.begin(write=True) as txn: for v in img_list: img = cv2.imread(v, cv2.IMREAD_UNCHANGED) if img is None: continue count += 1 pbar.update('Write {}'.format(v)) base_name = os.path.splitext(os.path.basename(v))[0] key = base_name.encode('ascii') # 获取图片维度信息 if img.ndim == 2: H, W = img.shape C = 1 else: H, W, C = img.shape meta_key = (base_name + '.meta').encode('ascii') meta = '{:d}, {:d}, {:d}'.format(H, W, C) txn.put(key, img) txn.put(meta_key, meta.encode('ascii')) print(f'Finish writing lmdb. 处理了 {count} 张图片,跳过 {len(failed_files)} 个损坏文件.')
4. 验证Drive挂载权限
确保Colab已正确挂载Google Drive,若挂载异常,重新执行挂载命令:
from google.colab import drive drive.mount('/content/drive')
内容的提问来源于stack exchange,提问作者Stud17
相关产品推荐
相关产品推荐

