我想循环处理一批文件,以便一次获取每个子目录的32张图像(由于内存原因,我无法加载所有图像),例如,加载每个目录的img 1-32 img使用它们然后加载img 33-64然后65-96等
我的目录:
Rootdir
- dir1
- img 1
- img 2
- img...
- dir2
- img 5000001
- img 5000002
- img...
- dir3
- img 10000001
- img 10000002
- img...
所以我需要在第一次循环时加载img1,2,.. 32,5000001,... 5000032,1000001,... 10000032,然后再加载img33,34,..,64,5000033,... 5000064 ,1000033,... 10000064在第二个循环
有没有办法正确地做到这一点?
我正在尝试使用os.walk,它允许我循环遍历目录,但是我看不到如何使此循环适应所需的32个批处理?
for dirName, subdirList, fileList in os.walk(rootdir):
print('Found directory: %s' % dirName)
for fname in sorted(fileList):
img_path = os.path.join(dirName, fname)
try:
img = load_img(img_path, target_size=None)
imgs.append(img)
except Exception as e:
print(str(e), fname, i)
#do something on imgs
编辑
您的所有评论都会给我这样的东西:
dir1 / img1.jpg到dir1 / img32.jpg,然后dir1 / img33.jpg到dir1 / img64.jpg然后 ...
然后将dir2 / img1.jpg转换为dir1 / img32.jpg,然后将dir2 / img33.jpg转换为dir2 / img64.jpg,然后...
然后将dir3 / img1.jpg转换为dir3 / img32.jpg,然后将dir3 / img33.jpg转换为dir3 / img64.jpg :(
我想要实现的是:
dir1 numero 1到32的文件+ dir2 numero 1到32的文件+ dir3 numero 1到32的文件
dir1 numero 33到64的文件+ dir2 numero 33到64的文件+ dir3 numero 33到64的文件在同一循环中
答案 0 :(得分:3)
os.walk已经返回了一个生成器,该生成器会即时生成一个三元组(目录路径,目录名,文件名)的值,因此您只需要批量生成32个文件名数组的切片即可。
这是一个示例:
import os
# Your root directory path
rootdir = r"Root"
#Your batch size
batch_size = 32
def walk_dirs(directory, batch_size):
walk_dirs_generator = os.walk(directory)
for dirname, subdirectories, filenames in walk_dirs_generator:
for i in range(0, len(filenames), batch_size):
# slice the filenames list 0-31, 32-64 and so on
yield [os.path.join(dirname, filename) for filename in filenames[i:i+batch_size]]
# Finally iterate over the walk_dirs function which itself returns a generator
for file_name_batch in walk_dirs(rootdir, batch_size):
for file_name in file_name_batch:
# Do some processing on the batch now
print (file_name)
pass
答案 1 :(得分:0)
您可以看看os.walk()
编辑:简单的计数器示例
counter = 0
for x in mylist:
# do something with x
todo_list.append(x)
counter += 1
if counter % 32 == 0:
# do something with todo list
todo_list = [] # empty todo list for next batch
答案 2 :(得分:0)
不需要Python脚本,可以使用命令行上的tree
命令来实现:
C:\Temp_Folder\images>tree /F
C:.
├───dir1
│ image1.jpg
│ image2.jpg
│ image3.jpg
│
├───dir2
│ image1.jpg
│ image2.jpg
│ image3.jpg
│
└───dir3
如果您想对这些文件进行处理,还可以使用forfiles
:
forfiles /S /M "*.jpg" /c "cmd /c echo @path\@file"
(这只是用于显示文件(echo
),但也可以使用其他命令行命令)
答案 3 :(得分:0)
总是使用相同的img列表并在拥有32张图像后立即对其进行处理?
for dirName, subdirList, fileList in os.walk('c:\\Java\\'):
print('Found directory: %s' % dirName)
for fname in sorted(fileList):
img_path = os.path.join(dirName, fname)
try:
img = load_img(img_path, target_size=None)
imgs.append(img)
if len(imgs) == 32:
print("Doing what I have to with current imgs list (add your function here)")
img = [] # cleaning img list
except Exception as e:
print(str(e))
#do something on imgs
如果您需要跟踪以前的所有列表,则只需复制列表内容即可。
让我知道您是否也想要该实现。
答案 4 :(得分:0)
好吧,我找到了一种方法,虽然不是最漂亮的,但是这里是: 我使用一个集合来知道我已经看过哪个文件,如果我在该文件上就继续,这样它就不计数了。
number_of_directory = 17
batch_size = 32
seen = set()
for overall_count in pbar(range(data_number // (batch_size * number_of_directory))):
imgs = []
for dirName, subdirList, fileList in os.walk(rootdir):
count = 0
for fname in sorted(fileList):
if fname in seen:
continue
if count == batch_size:
break
img_path = os.path.join(dirName, fname)
try:
img = cv2.imread(img_path, cv2.IMREAD_COLOR)
img = cv2.resize(img, (img_width, img_height))
imgs.append(np.array(img))
except Exception as e:
print(str(e), fname)
seen.add(fname)
count +=1
#Do something with images