I have dataset that consist of 100 folders and each of folders contain some images as shown below. How do I read this images and labels so that if I call the folder label, it will have collection of the images? (for example if I call Cat label, it will consist of img_001 and img_032 not just img_001 or img_032). I have tried using dictionary as my code below, but the dictionary only takes the first image of each folder, whereas I want to takes all images. How to do this? Thank you
(Folder Structure)
Cat:
-img_001.jpg
-img_032.jpg
Dog:
-img_002.jpg
-img_012.jpg
-img_011.jpg
-img_000.jpg
Bird:
-img_003.jpg
... until 100 folders
(My code)
path = 'animal/'
img_dict = dict()
for root, dirs, files in os.walk(path):
print(os.path.basename(root))
my_key = os.path.basename(root)
for file_ in files:
full_file_path = os.path.join(root, file_)
img = cv2.imread(full_file_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img_dict[my_key] = img
(Output using my code with only one images per labels)
Cat:
-img_001.jpg
Dog:
-img_002.jpg
Bird:
-img_003.jpg
... until end of dictionary (100 labels)
You are using a folder name as a key for the dictionary.
To store several files in this case you should use a list type as a value.
Using [] as a literal for list creation and the append() method to append a value to the list, try to do like this:
path = 'animal/'
img_dict = dict()
for root, dirs, files in os.walk(path):
print(os.path.basename(root))
my_key = os.path.basename(root)
dir_images = []
for file_ in files:
full_file_path = os.path.join(root, file_)
img = cv2.imread(full_file_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
dir_images.append(img)
img_dict[my_key] = dir_images
Related
path_school="/content/drive/MyDrive"
test_path=path_school+"//"+"test"
processedex_path=path_school+"//"+"test_ex"
for (path, dir, files) in os.walk(train_path):
for filename in files:
ext = os.path.splitext(filename)[-1]
test_folder_list = [f for f in os.listdir(path_school+'//'+'test')]
for f in os.listdir(test_path):
fol=os.path.splitext(f)[-1]
'''
os.makedirs(processedex_path+"//"+f)
'''
if ext == '.jpg':
img=Image.open ("%s/%s" % (path, filename)).convert('L')
img=img.resize((256,256))
img.save(processedex_path+"//"+f+"//"+"pre"+"_"+filename)
in 'test_path' there are a lot of folders like 'A356_4_50_TS_167' and in this folder there are images named '0232-0024.jpg'.
I want to save images in right place folder 'A356_4_50_TS_167' in 'processedex_path' folder.
This code saves every changed images in every folder.
Please help me to save images in right folders.
enter image description here
enter image description here
these are my original path and I want to save images in same named folder in 'test_ex'(=processedex_path) folder
enter image description here
but every images from every folders were saved in each folders not 2 images per one folder but 70 images per on folder I want to save 2images per one folder
thank u for answering
I can't run your code but I think you have too many for-loops
I would do
import os
from PIL import Image
path_school = "/content/drive/MyDrive"
# source & destination folder
test_path = os.path.join(path_school, "test")
processedex_path = os.path.join(path_school, "test_ex")
os.makedirs(processedex_path, exist_ok=True)
for subfolder in os.listdir(test_path):
# source & destination subfolder
src_subfolder = os.path.join(test_path, subfolder)
dst_subfolder = os.path.join(processedex_path, subfolder)
if os.path.isdir(src_subfolder): # check if it is really subfolder
os.makedirs(dst_subfolder, exist_ok=True)
for filename in os.listdir(src_subfolder):
if filename.lower().endswith( ('.jpg', '.png', 'webp') ):
# source & destination file
src_file = os.path.join(src_subfolder, filename)
dst_file = os.path.join(dst_subfolder, "pre_"+filename)
img = Image.open(src_file).convert('L')
img = img.resize((256, 256))
img.save(dst_file)
print('converted:', filename)
print('src:', src_file)
print('dst:', dst_file)
I am trying to read multiple images from 3 different folder. Each folder contain 100 images. I try 2 different code but I have no idea why the codes does not work. Anyone can help? Thanks
For example:
Cropped Matrix:Matrix1.png, Matrix2.png,...
Cropped Marks:Mark1.png, Mark2.png,...
Cropped Marks1:Mark1Q1.png, Mark1Q2.png,...
Output: Matrix1.png + Mark1.png + Mark1Q1.png
Code 1:
#1st
path1 = os.path.abspath("C:/Users/TSL/Desktop/Crop/Cropped Matrix/*.png")
path2 = os.path.abspath("C:/Users/TSL/Desktop/Crop/Cropped Marks/*.png")
path3 = os.path.abspath("C:/Users/TSL/Desktop/Crop/Cropped Marks1/*.png")
folder= os.path.join(path1, path2, path3)
def load(folder):
images = []
for filename in os.listdir(folder):
if filename.endswith(".png"):
img = cv2.imread(os.path.join(folder, filename))
if img is not None:
images.append(img)
return images
root = 'C:/Users/TSL/Desktop/Crop'
folders = [os.path.join(root, x) for x in ('Cropped Matrix', 'Cropped Marks', 'Cropped Marks1')]
all = [img for folder in folders for img in load(folder)]
cv2.imshow("Join img", all)
cv2.waitKey(0)
Code 2
#2nd
path1 = os.path.abspath('Cropped Matrix')
path2 = os.path.abspath('Cropped Marks')
path3 = os.path.abspath('Cropped Marks1')
folder= os.path.join(path1, path2, path3)
def load(folder):
images = []
for filename in os.listdir(folder):
if any([filename.endswith(x) for x in [".png"]]):
img = cv2.imread(os.path.join(folder, filename))
if img is not None:
images.append(img)
return images
folders = ['Cropped Matrix', 'Cropped Marks',]
for folder in folders:
images = load(folder)
read = cv2.imread(images)
cv2.imshow("Join images", read)
cv2.waitKey(0)
all is a list of images and you try to show it using imshow. To show all images one by one you can loop through all and show each with imshow.
Also, as #gold_cy correctly points out, all is a built in python function, so you should avoid using it as a variable name. Change it to something like all_images.
all_images = [img for folder in folders for img in load(folder)]
for i in all_images:
cv2.imshow("Image", i) #or however you want
cv2.waitKey(10) #or any suitable number
def load_img(img):
img = cv.imread(r"C:\Users\OneDrive\Desktop\Computer-Vision-with-Python\DATA\ **dynamic_img** ")
img = cv.cvtColor(img ,cv.COLOR_BRG2RGB)
return img
so this is the function.... what I want to do is call the function with any image from the destination folder and it should replace that dynamic_img with the name of the image
THANK YOU.
First you need to find all images in the directory:
import os
path = 'c:\\Users\\OneDrive\\and_so_on'
files = []
# r=root, d=directories, f = files
for r, d, f in os.walk(path):
for file in f:
if '.jpg' in file:
files.append(os.path.join(r, file))
Then you can just iterate over files.
How to copy all the images present in multiple sub-directories to another sub-directories corresponding for them using Python? I have the dataset home-folder containing N sub-folders, inside each sub folder a set of images. I want to apply processing on each image in sub-directories and move it into corresponding sub-directory, that is like creating a new dataset image form. A tree like below:
+Home-dir
----- +sub-dir1 --->img1,img2,img3,------imgN
----- +sub-dir2 --->img1,img2,img3,------imgN
----- +sub-dir3 --->img1,img2,img3,------imgN
..
----- +sub-dirN --->img1,img2,img3,------imgN
I want to get the following:
+Home-dir-process
----- +sub-dir-new1 --->img-new1,img-new2,img-new3,------img-newN
----- +sub-dir-new2 --->img-new1,img-new2,img-new3,------img-newN
----- +sub-dir-new3 --->img-new1,img-new2,img-new3,------img-newN
..
----- +sub-dir-newN --->img-new1,img-new2,img-new3,------img-newN
I'm able to copy all image in one directory into corresponding one directory as following:
path1='path\to\before\processing\image'
path2='path\to\save\after\processing\image'
listing = os.listdir(path1)
for file in listing:
im = Image.open(path1 + '\\' + file)
img = im.resize((img_rows, img_cols))
img.save(path2 + '\\' + file, "JPEG")
But I want to copy all images in multiple sub-directories into another sub-directories, can anyone please help me?
I revised my original answer because it really didn't do what you wanted, it basically only did what the code in your questions does—process all the image files in a single folder.
The driver function is named process_tree() and its job is to traverse the home directory's sub-directories looking for files in them that match any in a set of the user-specified filename patterns, and if any are found, to create the destination sub-directory, and then call a user-supplied function on each one of them, passing it the existing source file name and the desired output file name, along with any arguments the users wants also passed to the supplied function.
In this code below the sample user-specified function is named resize_image(). As the name implies, it only processes one image file.
Note that the processed images have the same name as the source images (i.e. no -_new suffix gets added to their filenames).
import fnmatch
import os
from PIL import Image
verbose = True # Global printing flag for vprint().
def process_tree(src, dst, patterns, processing_func, *args):
vprint(' src: "{src}"'.format(src=src))
vprint('dst: "{dst}"'.format(dst=dst))
vprint()
for dirpath, subdirs, filenames in os.walk(src, topdown=False):
vprint('PROCESSING dirpath: "{}"'.format(dirpath))
if dirpath == src: # Root src directory?
if not os.path.exists(dst):
vprint('CREATING dst root: "{dst}"'.format(dst=dst))
os.makedirs(dst) # Make root dest folder.
vprint()
continue # Don't process files in root folder.
# Determine sub-directory of src being processed.
src_subdir = os.path.relpath(dirpath, src)
dst_subdir = os.path.join(dst, src_subdir)
# Determine which files in dirpath match one or more of the patterns.
if isinstance(patterns, str):
patterns = (patterns,) # Convert to single element sequence.
processible = set(filename for pattern in patterns
for filename in fnmatch.filter(filenames, pattern))
if not processible:
vprint('no files to process') # Output directory not created.
else:
if os.path.isdir(dst_subdir):
vprint('PROCESSING directory "{}"'.format(dst_subdir))
elif os.path.exists(dst_subdir):
raise NotADirectoryError('Non-drectory "{}" exists"'.format(dst_subdir))
else:
vprint('CREATING directory "{}"'.format(dst_subdir))
os.makedirs(dst_subdir)
vprint('processing files:')
for filename in filenames:
if filename in processible:
src_file_path = os.path.join(dirpath, filename)
dst_file_path = os.path.join(dst_subdir, filename)
try:
processing_func(src_file_path, dst_file_path, *args)
except Exception as exc:
vprint(' EXCEPTION processing file:\n {!s}'.format(exc))
vprint()
vprint()
def resize_image(src, dst, scale_factor):
""" Resize image src by scale_factor and save result to dst. """
vprint('resizing image:\n'
' src: "{src}"\n'
' scale factor: {scale_factor}'.format(**locals()))
img = Image.open(src)
# Calcuate new size.
new_width = round(img.width * scale_factor)
new_height = round(img.height * scale_factor)
if new_width < 1 or new_height < 1:
vprint(' width and/or height of scaled version of image "{filename}"\n'
' is less than 1 pixel - skipped'.format(filename=os.path.basename(src)))
return
resampling_method = Image.BICUBIC
img = img.resize((new_width, new_height), resample=resampling_method)
img.save(dst)
vprint(' resized image saved to "{}"'.format(dst))
def vprint(*args, **kwargs):
""" Only prints if global flag is set. """
if verbose:
return print(*args, **kwargs)
if __name__ == '__main__':
inputpath = r'\my\path\to\_source_images'
outputpath = r'\my\path\to\_processed_images'
process_tree(inputpath, outputpath, ('*.jpg',), resize_image, .5)
In my file, I have a large number of images in jpg format and they are named [fruit type].[index].jpg.
Instead of manually making three new sub folders to copy and paste the images into each sub folder, is there some python code that can parse through the name of the images and choose where to redirect the image to based on the fruit type in the name, at the same time create a new sub folder when a new fruit type is parsed?
Before
TrainingSet (file)
apple.100.jpg
apple.101.jpg
apple.102.jpg
apple.103.jpg
peach.100.jpg
peach.101.jpg
peach.102.jpg
orange.100.jpg
orange.101.jpg
After
TrainingSet (file)
apple(file)
apple.100.jpg
apple.101.jpg
apple.102.jpg
apple.103.jpg
peach(file)
peach.100.jpg
peach.101.jpg
peach.102.jpg
orange(file)
orange.100.jpg
orange.101.jpg
Here’s the code to do just that, if you need help merging this into your codebase let me know:
import os, os.path, shutil
folder_path = "test"
images = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))]
for image in images:
folder_name = image.split('.')[0]
new_path = os.path.join(folder_path, folder_name)
if not os.path.exists(new_path):
os.makedirs(new_path)
old_image_path = os.path.join(folder_path, image)
new_image_path = os.path.join(new_path, image)
shutil.move(old_image_path, new_image_path)
If they are all formatted similarly to the three fruit example you gave, you can simply do a string.split(".")[0] on each filename you encounter:
import os
for image in images:
fruit = image.split(".")[0]
if not os.path.isdir(fruit):
os.mkdir(fruit)
os.rename(os.path.join(fruit, image))
As an idea, hope it helps
import os
from pathlib import Path
import shutil
folder_path = "images/"
nameList=[]
for image in os.listdir(folder_paths):
folder_name = image.split('.')[0]
nameList.append(folder_name)
for f in os.listdir(folder_paths):
Path(folder_name).mkdir(parents=True, exist_ok=True,mode=0o755)
des = folder_name +"/"+str(f)
old_path = folder_paths+str(f)
for path in nameList:
if f.endswith('.jpg'):
print(f)
if path == folder_name:
shutil.move(old_path, str(des))