shuffle the images dataset in a folder - python

I am reading the .jpg files from a folder, shuffling it using random.shuffle and then want to save it in a different folder.
But , it shuffles the images but when I store them in the folder it is again deshuffled and arranged in order.
import random
from glob import glob
import cv2
files = glob("/utkface/*.jpg")
random.shuffle(files)
for image_name in files:
#print(image_name)
image=cv2.imread(image_name)
name = image_name.split('/')[-1]
name = name.split('.')[0]
name = image_name.split('\\')[-1]
print(name)
cv2.imwrite("shuffle_utkdata4/" +name,image)

Related

How to read subfolders files of same name in a folder in python?

I couldn't find a suitable answer so I asked here.
My folder organized like this:
F:\WORKS\dataset\SOB\ben
and "ben" has three sub-folders "ad", "fib" & "pot". And all these subfolders have a same subfolder named 'XC' in them. 'XC' has different type of ".png" files. No, I want to read all the "XC" subfolders ".png" files at once with python.
Is that possible? I need this because I have to relocate all "XC" subfolders file at one place.
Thanks.
I have tried to Solve it, but furthest I can get to relocate all ".png" files for 'ben' folder at once.
The code I tried:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import os
from os import listdir
from tqdm import tqdm
import shutil
%matplotlib inline
os.mkdir('augmented')
os.mkdir('augmented/ben')
def getListOfFiles(dirName):
listOfFile = os.listdir(dirName)
allFiles = list()
for entry in listOfFile:
fullPath = os.path.join(dirName, entry)
if os.path.isdir(fullPath):
allFiles = allFiles + getListOfFiles(fullPath)
else:
allFiles.append(fullPath)
return allFiles
files_ben = getListOfFiles('/content/drive/MyDrive/Works/dataset/SOB/ben')
for f in files_ben:
if f.endswith('.png'):
shutil.copy(f,'augmented/ben')
import os
# Set the directory path
directory = r"F:\WORKS\dataset\SOB\ben"
# Loop over all the subdirectories in the directory
for root, dirs, files in os.walk(directory):
# Check if the current directory is an XC directory
if os.path.basename(root) == "XC":
# Loop over all the files in the directory
for file in files:
# Check if the file is a PNG file
if file.endswith(".png"):
# Do something with the file
print(os.path.join(root, file))

.DS_Store Error in Random Image Selection

i'm trying to make something that returns a random image from a folder to eventually put together an outfit. the path is a specific folder, as each path is a different type of clothing article (i.e. a folder/path for pants would be /Users/xxx/Desktop/outfit_images/5pants)
def article(path):
files = os.listdir(path) # listdir gives you a list with all filenames in the provided path.
randomFile = random.choice(files) # random.choice then selects a random file from your list
image = Image.open(path + '/' + randomFile) # displayed the image
return image
i'm using the code above to have the specified clothing article file as the input, and then select a random image from that file. i however, get errors (.DS_Store selection error) every few attempts becuase of the hidden files on the mac '.', '..', and want to figure out how to avoid selecting these hidden files. i would prefer to use a method other than running the rm from the terminal. any help is greatly appreciated!
You can use glob for this:
import glob
import os
def article(path):
files = glob.glob(os.path.join(path, '*'))
randomFile = random.choice(files)
image = Image.open(path + '/' + randomFile)
return image

Naming images based on CSV file which include two columns {image_id, label}

I have a folder that includes a big amount of images (five categories of vegetables) have certain names (image ID), also I have a CSV file, which includes two columns, the first is the images ID, and the second is the label (each image ID is paired with label 0,1,2,3 or 4)
How can I rename the images in this folder to take the labels as a new name using python?!
You can just rename your files using standard os module
import os
os.rename('YOU_CURRENT_IMAGE_NAME.jpg', 'NEW_NAME.jpg')
let's assume that you have an image with name my_pic.jpg and you want to rename it with ID=abc and labe=2, then code looks like this:
import os
def rename_image(existing_name, _id, label):
existing_name = 'my_pic.jpg'
extension = existing_name.split('.')[-1]
new_name = f'{_id}-{label}.{extension}'
os.rename(existing_name, new_name)
rename_image('my_pic.jpg', 'abc', 2)
# new name is: abc-2.jpg
[EDITED]
Let's assume that you have a folder called 'images', all your images are stored in this folder, and you have a csv file like this:
old_name1.jpg,new_name_001.jpg
another_old_pic.svg,new_name_for_this.svg
A simple snippet to rename all files in this case would be like this:
import os
import csv
IMG_FOLDER = 'images' # name of your image folder
CUR_PATH = os.getcwd() # current working directory
img_dir = os.path.join(CUR_PATH, IMG_FOLDER) # full path to images folder
with open('images.csv') as csv_file:
csv_data = csv.reader(csv_file)
images = os.listdir(img_dir) # a list of file names in images folder
for row in csv_data:
# we iterate over each row in csv and rename files
old_name, new_name = row
# we are just checking in case file exists in folder
if old_name in images:
# main part: renaming the file
os.rename(
os.path.join(CUR_PATH, IMG_FOLDER, old_name),
os.path.join(CUR_PATH, IMG_FOLDER, new_name)
)
else:
print(f"Image {old_name!r} not found, skipping...")
You can tweak the renaming part, and add anything you want to new image name (you wanted to include some kind of label, I guess?).

i can not images using cv2.imwrite () method

I want to copy all the pictures from one folder to another folder. I tried to run this code again and again but it returns me False only instead of saving pictures to other folder.
import cv2
import glob
input_path = 'C:\\Users\\Kazmi-PC\\OneDrive\\Pictures\\1\\*.*'
output_path = 'C:\\Users\\Kazmi-PC\\OneDrive\\Pictures\\2\\*.jpg'
for file in glob.glob(input_path):
print("printing.....")
print(file)
a= cv2.imread(file)
cv2.imwrite(output_path, a)
You can't use * in output filename. You would have to use imwrite inside for loop and use unique filenames in output.
You can use shutil.copy(file, directory) to copy. So you can use output without *.jpg and you don't have to add filename in output.
But you still need to copy every file separatelly.
import glob
import shutil
input_path = 'C:\\Users\\Kazmi-PC\\OneDrive\\Pictures\\1\\*.*'
output_dir = 'C:\\Users\\Kazmi-PC\\OneDrive\\Pictures\\2\\'
for file in glob.glob(input_path):
shutil.copy(file, output_dir)

Pick number of files instead of percentage

I have modified the following code for my needs.
It randomly moves files from one directory to another.
Currently it is copying a percentage of files from one folder to another. What do I need to change to copy 3 files rather than a percentage?
Is this the bit I need to change?
"*.02)):"
My code:
import os, shutil
from random import choice
rootdir = '/Autoupload'
output_dir = '/Public'
for subdir, dir, files in os.walk(rootdir):
if files:
for x in range(int(len(files) *.02)):
to_copy = choice(files)
shutil.move(os.path.join(subdir, to_copy), os.path.join(output_dir, to_copy))
files.remove(to_copy)
Using random.sample can do the trick for you:
import os, shutil
from random import sample
rootdir = '/Autoupload'
output_dir = '/Public'
for subdir, dir, files in os.walk(rootdir):
for to_copy in sample(files, min(len(files), 3)): # <- at most 3 files from each dear
shutil.move(os.path.join(subdir, to_copy), os.path.join(output_dir, to_copy))

Categories

Resources