joasa
joasa

Reputation: 976

Python Read multiple images from multiple folders

I want to read multiple .jpg images, that are in 3 separate folders. The 3 folders are on the same path. I tried to do it like this:

path1 = os.path.abspath('Type_1')
path2 = os.path.abspath('Type_2')
path3 = os.path.abspath('Type_3')
folder = os.path.join(path1, path2, path3)

def load_images_from_folder(folder):
    images = []
    for filename in os.listdir(folder):
        if filename.endswith(".jpg"):
            img = cv2.imread(os.path.join(folder, filename))
            if img is not None:
                images.append(img)
            return images

print(load_images_from_folder(folder))

But it only returns the last path and not all of them. I also tried to use relative paths, such as:

path1 = os.path.relpath('Type_1')
path2 = os.path.relpath('Type_2')
path3 = os.path.relpath('Type_3')
folder = os.path.join(os.path.sep, path1, path2, path3)

but still the same problem. Can someone help with this?

Upvotes: 1

Views: 14929

Answers (3)

Sadiq
Sadiq

Reputation: 21

I know this is really old, but this worked for me recently.

 def create_dataset(img_folder):
    img_data_array=[]
    class_name=[]

    for dirl in os.listdir(img_folder):
        for file in os.listdir(os.path.join(img_folder,dirl)):
        
            if any([file.endswith(x) for x in ['.jpeg', '.jpg']]):
            

                 image_path=os.path.join(img_folder,dirl,file)
                 image=cv2.imread(image_path,cv2.COLOR_BGR2RGB)
             
                 img_data_array.append(image)
                 class_name.append(dirl)
    return img_data_array,class_name


img_data, class_name =create_dataset(train_folder)
        

Upvotes: 0

initialed85
initialed85

Reputation: 184

If I understand the problem correctly, your file structure looks as follows:

- Type1
    - Image1.jpg
    - Image2.jpg
- Type2
    - Image1.jpg
    - Image2.jpg
- Type3
    - Image1.jpg
    - Image2.jpg

If this is true, then the os.path.join call is errant (it'll result in a string that reads "Type1/Type2/Type3" which achieves nothing for you).

I think the code you're looking for is as follows:

def load_images_from_folder(folder):
    images = []
    for filename in os.listdir(folder):
        if any([filename.endswith(x) for x in ['.jpeg', '.jpg']]):
            img = cv2.imread(os.path.join(folder, filename))
            if img is not None:
                images.append(img)
    return images

folders = [
    'Type1',
    'Type2',
    'Type3',
]

for folder in folders:
    images = load_images_from_folder(folder)
    # your code that does something with the return images goes here

Upvotes: 3

khelwood
khelwood

Reputation: 59096

Your return images line is inside your loop, so it will return as soon as it finds any matching result. You only want it to return after the whole loop as finished.

Reduce the indentation of the return statement so that it lies after the loop instead of inside it.

def load_images_from_folder(folder):
    images = []
    for filename in os.listdir(folder):
        if filename.endswith(".jpg"):
            img = cv2.imread(os.path.join(folder, filename))
            if img is not None:
                images.append(img)
    return images

[Edit]

If you want to look in multiple adjacent folders, you want something like this:

root_folder = '[whatever]/data/train'
folders = [os.path.join(root_folder, x) for x in ('Type_1', 'Type_2', 'Type_3')]
all_images = [img for folder in folders for img in load_images_from_folder(folder)]

That will call load_images on each folder, and put all the results into one list.

Upvotes: 4

Related Questions