代码之家  ›  专栏  ›  技术社区  ›  StuckInPhDNoMore

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

  •  0
  • StuckInPhDNoMore  · 技术社区  · 8 年前

    我必须用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 回复  |  直到 8 年前
        1
  •  3
  •   TheBlackCat    8 年前

    第一个问题是 n 不是数字或索引,而是包含路径名的字符串。要获取索引,可以使用 enumerate ,从而 index 我是说, value 对。

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

    第三,最好不要使用变量 file 因为在Python2中,它是一种内置的数据类型,所以可能会让人感到困惑。

    因此,对于预分配,这应该是有效的:

    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)]
    

    使用append,应该可以:

    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()]
    
        2
  •  1
  •   Jeru Luke    8 年前

    应该是:

    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))
    
        3
  •  1
  •   m0etaz    8 年前
    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()