Displaying random images from multiple folders using python

Question:

python v 3.7.3
matplotlib 3.1.1
running on Google colab

I have a dataset containing 101 folders, with about 750 images per folder. I would like to randomly display 16 of these images, from any given folder. The images are organized as such:

Train directory

  • folder1
  • —> image1
  • —> image2
  • —> imagen
  • folder2
  • —> image1
  • —> image2

and so on.

I tried to create code that iterates through each folder and selects a random image 16 times TOTAL (not per folder).

Here is my code thus far:

import random
from PIL import Image 

for folder in os.listdir(train_folder):
  for image in os.listdir(train_folder + '/' + folder):
    img = os.path.join(train_folder, folder, image)
    #print(img)

    plt.figure(1, figsize=(15, 9))
    plt.axis('off')
    n = 0
    for i in range(16):
      n += 1
      random_img = random.choice(img)
      imgs = imread(random_img)
      plt.subplot(4, 4, n)
      axis('off')
      plt.imshow(imgs)

plt.show()

Here is the error:

FileNotFoundError                         Traceback (most recent call last)
<ipython-input-19-2f47ab853e7c> in <module>()
     13       n += 1
     14       random_img = random.choice(img)
---> 15       imgs = imread(random_img)
     16       plt.subplot(4, 4, n)
     17       #plt.subplots_adjust(hspace = 0.5, wspace = 0.5)

1 frames
/usr/local/lib/python3.6/dist-packages/PIL/Image.py in open(fp, mode)
   2764 
   2765     if filename:
-> 2766         fp = builtins.open(filename, "rb")
   2767         exclusive_fp = True
   2768 

FileNotFoundError: [Errno 2] No such file or directory: '6'

I am not sure where to present the argument to randomly select one of the images. I also think that the structure I am using might not be the most efficient, as it may require multiple iterations through the folders. It would be nice for it to just go through the folders once, and select 16 images. Is there an efficient way to do this in python? I do not know its limitations yet.

Asked By: Sanglang

||

Answers:

os.path.join concatenates the paths, but it doesn’t make a list from which you can randomly pick path names. You also need to separate out generating the list and randomly picking from it.
Try something like:

import random
from PIL import Image 

images = []
for folder in os.listdir(train_folder):
  for image in os.listdir(train_folder + '/' + folder):
    images.append(os.path.join(train_folder, folder, image))

plt.figure(1, figsize=(15, 9))
plt.axis('off')
n = 0
for i in range(16):
  n += 1
  random_img = random.choice(images)
  imgs = imread(random_img)
  plt.subplot(4, 4, n)
  axis('off')
  plt.imshow(imgs)

plt.show()

Hope that helps!

Answered By: minterm

This is one solution to your question, you can reference it. I hope it can help you a lot!
If you have any question, you can email me!

import random
from PIL import Image
import os

path = os.getcwd()+'\'+"Question1"
dirs = os.listdir(path)
image_random_number = 16
for folder in os.listdir(path):
    image_lists = os.listdir(path+'\'+folder)
    for i in range(image_random_number):
        index = random.randint(1,image_random_number)
        image = image_lists[index]
        img = os.path.join(path,folder,image)
        im = Image.open(img)
        im.show()
Answered By: Dejun E

I use this solution:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import random

def view_random_image(target_dir, target_class):
  target_folder = target_dir + target_class
  random_image = random.sample(os.listdir(target_folder), 1)
  img = mpimg.imread(target_folder + '/' + random_image[0])
  plt.imshow(img)
  plt.title(target_class)
  plt.axis('off')

I hope this will be helpful

Answered By: Rüstəm alızadə
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.