首页 > 解决方案 > 问题排序文件夹中的文件“ValueError:int()的无效文字,基数为10:''

问题描述

我正在尝试读取文件夹“frames”的文件名并对其进行排序,但出现错误。我的代码如下:

col_frames = os.listdir(path + 'frames/')

# sort file names
col_frames.sort(key=lambda f: int(re.sub('\D', '', f)))

# empty list to store the frames
col_images=[]

for i in col_frames:
    # read the frames
    img = cv2.imread(path + 'frames/'+i)
    # append the frames to the list
    col_images.append(img)

我收到了这个错误:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-17-6300f903ade1> in <module>
      6 
      7 # sort file names
----> 8 col_frames.sort(key=lambda f: int(re.sub('\D', '', f)))
      9 
     10 # empty list to store the frames

<ipython-input-17-6300f903ade1> in <lambda>(f)
      6 
      7 # sort file names
----> 8 col_frames.sort(key=lambda f: int(re.sub('\D', '', f)))
      9 
     10 # empty list to store the frames

ValueError: invalid literal for int() with base 10: ''

我确实将其转换为整数。你能解释一下发生了什么,如果有办法解决吗?

打印时print(col_frames)我得到这个:['348.png', '1186.png', '412.png', '374.png', '360.png', '406.png', '1192.png', '1179.png', '1145.png', '1623.png', '1637.png', '1151.png', '638.png', '176.png', '88.png', '610.png', '1384.png', '1390.png', '604.png', '162.png', '189.png', '837.png', '77.png', '823.png', '63.png', '1409.png', '1421.png', '1347.png', '1353.png', '1435.png', '980.png', '758.png', '994.png', '1596.png', '764.png', '770.png', '1582.png', '1569.png', '943.png',....]

标签: python

解决方案


直接原因是目录中至少有一项在其名称中没有任何数字。我可以想到这可能发生的两个主要原因:

  1. 该目录包含除您的图像之外的一项或多项。它们可能是子目录、其他随机文件,或者更有可能是操作系统使用的隐藏文件,例如.DS_Store在 macOS 上。

  2. 您的一张或多张图片的命名方式与您期望的图片命名方式不同。

首先,让我们假设#1。这是只检查 .png 图像的代码,使用 Python 的模块pathlib,它比. cv2 还不完全支持它。os

from pathlib import Path

# Presumably your base path is defined above as a string. Here we make a Path
# object out of it.
path = Path(path)

# Get all *.png files 
frame_files = (path / 'frames').glob('*.png')

# Sort file names by the filename (minus extension) as an int
frame_files.sort(key=lambda f: int(f.stem))

# Build list
frames = [cv2.imread(str(path / 'frames' / frame_file))
          for frame_file in frame_files]

我将最后一部分更改为list comprehension,但如果您发现它更具可读性,也可以将其保留为 for 循环:

frames = []
for frame_file in frame_files:
    frames.append(cv2.imread(str(path / 'frames' / frame_file)))

如果这引发相同的错误,那么您至少知道您的帧图像文件有一个格式错误的文件名。您可以通过以下方式找到它/它们:

for frame_file in frame_files:
    if not frame_file.stem.isdigit():
        print(frame_file)

您需要cv2.imread(str(path / 'frames' / frame_file))(或者可能是cv2.imread(str(frame_file.resolve())YMMV)的唯一原因是因为 python-cv2还没有像原生 Python 工具那样完全支持 Path 对象open()。如果改进了,你就可以简单地做cv2.imread(frame_file),因为每个 Path 对象不仅仅是一个字符串;它已经知道它的位置。

我在 Github 问题上添加了关于这一事实的评论,以添加更多的支持声音。


推荐阅读