在保持文件夹结构的同时读取图像

时间:2018-07-17 17:00:23

标签: python matlab opencv

我必须用python写一个matlab脚本,因为我想实现的目标显然是在Python中更有效地完成的。

因此,第一个任务是在保持文件夹结构的同时,使用opencv将所有图像读入python。例如,如果父文件夹有50个子文件夹,而每个子文件夹有10张图像,则images变量在python中应该是这样,非常像matlab中的单元格。我读到python列表可以在不导入任何内容的情况下执行类似于单元格的行为,所以我猜这很好。

例如,以下是我在Matlab中进行编码的方式:

path = '/home/university/Matlab/att_faces';

subjects = dir(path);
subjects = subjects(~strncmpi('.', {subjects.name}, 1)); %remove the '.' and '..' subfolders
img = cell(numel(subjects),1); %initialize the cell equal to number of subjects

for i = 1: numel(subjects)
    path_now = fullfile(path, subjects(i).name);
    contents = dir([path_now, '/*.pgm']);
    for j = 1: numel(contents)
        img{i}{j} = imread(fullfile(path_now,contents(j).name));
        disp([i,j]);
    end
end

以上img将有50个单元格,每个单元格将存储10张图像。 img{1}将是属于主题1的所有图像,依此类推。

我正在尝试在python中复制它,但是失败了,这就是我到目前为止所得到的:

import cv2
import os
import glob


path = '/home/university/Matlab/att_faces'

sub_f = os.listdir(path)
images = []
for n in sub_f:
    path_now = os.path.join(path, sub_f[n], '*.pgm')
    images[n] = [cv2.imread(file) for file in glob.glob(path_now)]

这并非我所要寻找的,有些帮助将不胜感激。请忽略愚蠢的错误,因为这是我用python编写的第一天。

谢谢

编辑:目录结构:

enter image description here

3 个答案:

答案 0 :(得分:3)

第一个问题是n不是数字或索引,它是包含路径名的字符串。要获取索引,可以使用enumerate,它给出indexvalue对。

第二,与在MATLAB中不同,您不能将其分配给不存在的索引。您需要预先分配图像数组,或者更好的是,将其追加到它。

第三,最好不要使用变量file,因为在python 2中它是内置的数据类型,因此可能会使人感到困惑。

因此,通过预分配,这应该可以工作:

images = [None]*len(sub_f)
for n, cursub in enumerate(sub_f):
    path_now = os.path.join(path, cursub, '*.pgm')
    images[n] = [cv2.imread(fname) for fname in glob.glob(path_now)]

使用附加,这应该可以工作:

for cursub in sub_f
    path_now = os.path.join(path, cursub, '*.pgm')
    images.append([cv2.imread(fname) for fname in glob.glob(path_now)])

话虽这么说,但有一种更简单的方法可以做到这一点。您可以使用pathlib模块来简化此过程。

所以这样的事情应该起作用:

from pathlib import Path

mypath = Path('/home/university/Matlab/att_faces')
images = []

for subdir in mypath.iterdir():
    images.append([cv2.imread(str(curfile)) for curfile in subdir.glob('*.pgm')])

这会遍历子目录,然后遍历每个子目录。

这甚至可以在嵌套列表理解中完成:

images = [[cv2.imread(str(curfile)) for curfile in subdir.glob('*.pgm')]
          for subdir in mypath.iterdir()]

答案 1 :(得分:1)

应为以下内容:

import os
path = '/home/university/Matlab/att_faces'

sub_f = os.listdir(path)
print(sub_f)    #--- this will print all the files present in this directory ---

#--- this a list to which you will append all the images ---
images = []


#--- iterate through every file in the directory and read those files that end with .pgm format ---
#--- after reading it append it to the list ---
for n in sub_f:
    if n.endswith('.pgm'):
        path_now = os.path.join(path, n)
        print(path_now)
        images.append(cv2.imread(path_now, 1))

答案 2 :(得分:1)

import cv2
import os
import glob

path = '/home/university/Matlab/att_faces'

sub_f = os.listdir(path)
images = []

#read the images
for folder in sub_f:
    path_now = os.path.join(path, folder, '*.pgm')
    images.append([cv2.imread(file) for file in glob.glob(path_now)])

#display the images
for folder in images:
    for image in folder:
        cv2.imshow('image',image)
        cv2.waitKey(0)
        cv2.destroyAllWindows()