I am running a code in python where I get images from input file, and create another folder as output and a file csv. The code that I run is as below:
# import the necessary packages
from PIL import Image
import argparse
import random
import shutil
import glob2
import uuid
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--input", required = True,
help = "input directory of images")
ap.add_argument("-o", "--output", required = True,
help = "output directory")
ap.add_argument("-c", "--csv", required = True,
help = "path to CSV file for image counts")
args = vars(ap.parse_args())
# open the output file for writing
output = open(args["csv"], "w")
# loop over the input images
for imagePath in glob2.iglob(args["input"] + "/*/*.jpg"):
# generate a random filename for the image and copy it to
# the output location
filename = str(uuid.uuid4()) + ".jpg"
shutil.copy(imagePath, args["output"] + "/" + filename)
# there is a 1 in 500 chance that multiple copies of this
# image will be used
if random.randint(0, 500) == 0:
# initialize the number of times the image is being
# duplicated and write it to the output CSV file
numTimes = random.randint(1, 8)
output.write("%s,%d\n" % (filename, numTimes))
# loop over a random number of times for this image to
# be duplicated
for i in range(0, numTimes):
image = Image.open(imagePath)
# randomly resize the image, perserving aspect ratio
factor = random.uniform(0.95, 1.05)
width = int(image.size[0] * factor)
ratio = width / float(image.size[0])
height = int(image.size[1] * ratio)
image = image.resize((width, height), Image.ANTIALIAS)
# generate a random filename for the image and copy
# it to the output directory
adjFilename = str(uuid.uuid4()) + ".jpg"
shutil.copy(imagePath, args["output"] + "/" + adjFilename)
# close the output file
output.close()
After running the code I get only csv file, but I don't get output folder.
The way I run the code is:
python gather.py --input 101_ObjectCategories --output images --csv output.csv
Please can you help me how to solve the problem, because I need the output folder for next steps, running next functions.
I would recommend the following approach:
import os
from pathlib import Path
Path('path').mkdir(parents=True, exist_ok=True)
This works cross-platform and doesn't overwrite the directories if they already exist.
You should try the os module. It has a mkdir method that creates a directory based on the path you give it as a parameter.
import os
os.mkdir("path")
While most answers suggest using os.mkdir() I suggest you rather go for os.makedirs() which would recursively create all the missing folders in your path, which usually is more convinient.
import os
os.makedirs('foo/bar')
Docs: https://docs.python.org/3/library/os.html#os.makedirs
Related
I was cropping about hundreds of videos to crop the first 30 seconds of each clip. The code is working for one clip but when I put path, the code starts to not work.
I pasted the current code with what I tried below. Could I get an insight on how I could iterate every file in the folder?
Thank you
import os
import ffmpeg
from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip
from moviepy.editor import *
def timeCrop():
directory = "/Users/documents/lab/video/ProccessedVideo"
count = 1
for filename in os.listdir(directory):
if filename.endswith(".mpg") or filename.endswith(".mp4"):
path = os.path.join(directory, filename)
input = ffmpeg.input(path)
print(path, count)
mice = ["022, 90"]
ffmpeg_extract_subclip("{path}.mpg", 30, 120, targetname="{mice[0]}.mpg, {mice[1]}.mpg")
count += 1
def timeCrop2():
directory = "/Users/documents/lab/video/ProccessedVideo"
clip = VideoFileClip("022.mpg").cutout(0, 30)
clip.write_videofile("022e.mpg", codec="libx264")
#timeCrop()
timeCrop2()
You can iterate each files in the directory with filter for example (.mp4) using the code below
import os
directory = os.fsencode("D:\\Acroyoga")
for file in os.listdir(directory):
filename = os.fsdecode(file)
if filename.endswith(".mp4"):
print(filename) #do your video process here
continue
else:
continue
Im trying to write a python script which will walk through a directory and traverse the all sub directories and if any jpg or png image has higher resolution than 2048*2048 then print out the name of those images. I am not able to traverse the sub-directories. Can anyone plz look into the code
import os
import matplotlib.image as plt
root_path = 'E:\newfolder'
img_list = os.listdir(root_path)
for img_name in img_list:
if img_name.endswith(('.png', '.jpg')):
img = plt.imread(root_path+'/'+img_name)
if img.shape[0] > 2048 and img.shape[1] > 2048:
print(root_path, img_name)
Here's a complete and tested solution that is similar to answers by #Paul and #BrainCity. You'll see that I prefer using small, clear functions, since these encourage reusable code.
You can do the image processing using matplotlib as you do in your question, but you need to install Pillow in order to handle .JPG images, since matplotlib only supports PNG natively. I prefer using Pillow directly unless you're already using matplotlib for other stuff.
from pathlib import Path
from PIL import Image
def print_high_res_images(directory: str):
root_path = Path(directory).resolve()
high_res_images = get_high_res_images(root_path)
if high_res_images:
print('High resolution images:')
for file_path in high_res_images:
print(file_path)
def get_high_res_images(root_path: Path) -> []:
return [path for path in root_path.rglob("*.*") if is_high_res_image(path)]
def is_high_res_image(file_path: Path) -> bool:
if is_image(file_path):
image = Image.open(file_path)
width, height = image.size
return width > 2048 and height > 2048
return False
def is_image(file: Path) -> bool:
return file.suffix.lower() in ['.png', '.jpg']
# Test our new function:
print_high_res_images(r'E:\newfolder')
If you're using Python 3.5+, you can use the pathlib module, and then use a recursive glob pattern to find all files in all subdirectories. Then, you filter the paths and retain only those whose suffix is .png or .jpg:
from pathlib import Path
for path in [path for path in Path("dir/to/images").rglob("*.*") if path.suffix.lower() in (".png", ".jpg")]:
# image = Image(path)
# if image dimensions greater than 2048 x 2048:
# print(path)
print(path) will print out the entire absolute path of the current image, but if you just want to print out the name, you can print(path.name), which will include the suffix (file extension). If you just want the name of the file without the extension, you can print(path.stem).
crawl subdirectory using os.walk
import os
import pathlib
from PIL import Image
def crawlImages(directory):
allowedExtensions = ['.jpg', '.png']
for root, dirs, files in os.walk(directory):
for f in files:
if pathlib.Path(f).suffix in allowedExtensions:
fileName = os.path.abspath(os.path.join(root, f))
image = Image.open(fileName)
width, height = image.size
# checking minimum image width and height
if width > 2400 and height > 2400:
print(fileName, width, height)
crawlImages('E:\\music')
I'm in an introductory neural networking class so mind my ignorance. Also my first SO post.
I'm trying to resize some very highly resolved images within a dataset into 80x80p grayscale images in a new dataset. However, when I do this, I'd like to keep the filenames of each new image the same as the original image. The only way I know how to resave images into a new file is through a str(count) which isn't what I want. The filenames are important in creating a .csv file for my dataset later.
The only SO post I can find that is related is this:
Use original file name to save image
But the code suggested there didn't work - wasn't sure if I was going about it the wrong way.
import os
from PIL import Image
import imghdr
count=0
path1 = "/Users/..."
path2 = "/Users/..."
listing = os.listdir(path1)
for file in listing:
type = imghdr.what((path1 + file))
if type == "jpeg":
img = Image.open("/Users/..." +file).convert('LA')
img_resized = img.resize((80,80))
img_resized.save(path2 + str(count) + '.png')
count +=1
pass
pass
Reuse the original filename that you get from the for loop i.e. file
and, split it into filename and extension using os.path.splitext() like below:
import os
from PIL import Image
import imghdr
count=0
path1 = "/Users/..."
path2 = "/Users/..."
listing = os.listdir(path1)
for file in listing:
type = imghdr.what((path1 + file))
if type == "jpeg":
img = Image.open("/Users/..." +file).convert('LA')
img_resized = img.resize((80,80))
# splitting the original filename to remove extension
img_filename = os.path.splitext(file)[0]
img_resized.save(path2 + img_filename + '.png')
count +=1
pass
Another option, we can use python str's built-in split method to split the original filename by . and discard the extension.
import os
from PIL import Image
import imghdr
count=0
path1 = "/Users/..."
path2 = "/Users/..."
listing = os.listdir(path1)
for file in listing:
type = imghdr.what((path1 + file))
if type == "jpeg":
img = Image.open("/Users/..." +file).convert('LA')
img_resized = img.resize((80,80))
# splitting the original filename to remove extension
img_filename = file.split(".")[0]
img_resized.save(path2 + img_filename + '.png')
count +=1
pass
So, if an image has a name such as some_image.jpeg then, the img_filename will have a value some_image as we splitted by . and discarded .jpeg part of it.
NOTE: This option assumes the original_filename will not contain any . other than the extension.
I assume that image name is on path1. If so you can grap image name from there in this way:
x=path1.rsplit('/',1)[1]
We are splitting path1 on last slash and taking image name string via indexing.
after having concatenated 10 strips of the same image, I want to convert them into reflectance and therefore divide them by 10,000. Nevertheless I have two types of files in my folders, except I want to apply my code only to my.img file and not to the.hdr...
Do you know how I can proceed to make this selection with os.listdir?
my code is as follows :
import os
import spectral as sp
import spectral.io.envi as envi
src_directory = "/d/afavro/Bureau/3_stack/"
dossier = os.listdir (src_directory)
print(dossier)
for fichier in dossier:
print (fichier)
ssrc_directory = "/d/afavro/Bureau/3_stack/" + fichier
rasters = os.listdir (ssrc_directory)
print(rasters)
OUTPUT_FOLDER = "/d/afavro/Bureau/4_reflectance/" + 'reflectance_' + fichier
print(OUTPUT_FOLDER)
if not os.path.exists(OUTPUT_FOLDER):
os.makedirs(OUTPUT_FOLDER)
for image in rasters:
print (image)
img = sp.open_image(image)
print("%s opened successfully" %os.path.basename(image))
im_HS = img[:,:,:]/10000
header = envi.read_envi_header('/d/afavro/Bureau/3_stack/'+ image)
#Save index image
sp.envi.save_image(OUTPUT_FOLDER + '/reflectance_' + image, im_HS, metadate = header, force = True, interleave = 'bsq')
I think that making a yew loop would be a good idea but I don't know how to do it...
Ideas ?
Find the extension of the file using os.path.splitext
for f in os.listdir('<path>'):
name, ext = os.path.splitext(f)
if ext == '.img':
#do stuff
Why don't you use glob?
from glob import glob
for f in glob('/your/path/*.img'):
pass # add your code here
Hello You can use use Pathlib as an object oriented Path management library
and do something like
from Pathlib2 import Path
pattern_1 = "type1"
pattern_2 = "type2"
list_pattern_1_files = list(Path(<YOUR_PATH>).glob(f'**/*.{pattern_1}'))
list_pattern_2_files = list(Path(<YOUR_PATH>).glob(f'**/*.{pattern_2}'))
So I'm working on this sign language gesture recognition python project from git hub.
I followed the read me file and saved (in the project's root folder) all the dataset files in two seperate folders named as train_videos and test_videos for machine learning.
Now I'm getting the following error:
usage: video-to-frame.py [-h] gesture_folder target_folder
video-to-frame.py: error: the following arguments are required: gesture_folder, target_folder
Following is the code from "video-to-frame.py" file.
I can't figure out where to put the paths of my data set fodlers.
import cv2
import os
import pickle
from os.path import join, exists
import handsegment as hs
import argparse
from tqdm import tqdm
hc = []
def convert(gesture_folder, target_folder):
rootPath = os.getcwd()
majorData = os.path.abspath(target_folder)
if not exists(majorData):
os.makedirs(majorData)
gesture_folder = os.path.abspath(gesture_folder)
os.chdir(gesture_folder)
gestures = os.listdir(os.getcwd())
print("Source Directory containing gestures: %s" % gesture_folder)
print("Destination Directory containing frames: %s\n" % majorData)
for gesture in tqdm(gestures, unit='actions', ascii=True):
gesture_path = os.path.join(gesture_folder, gesture)
os.chdir(gesture_path)
gesture_frames_path = os.path.join(majorData, gesture)
if not os.path.exists(gesture_frames_path):
os.makedirs(gesture_frames_path)
videos = os.listdir(os.getcwd())
videos = [video for video in videos if(os.path.isfile(video))]
for video in tqdm(videos, unit='videos', ascii=True):
name = os.path.abspath(video)
cap = cv2.VideoCapture(name) # capturing input video
frameCount = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
lastFrame = None
os.chdir(gesture_frames_path)
count = 0
# assumption only first 200 frames are important
while count < 201:
ret, frame = cap.read() # extract frame
if ret is False:
break
framename = os.path.splitext(video)[0]
framename = framename + "_frame_" + str(count) + ".jpeg"
hc.append([join(gesture_frames_path, framename), gesture, frameCount])
if not os.path.exists(framename):
frame = hs.handsegment(frame)
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
lastFrame = frame
cv2.imwrite(framename, frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
count += 1
# repeat last frame until we get 200 frames
while count < 201:
framename = os.path.splitext(video)[0]
framename = framename + "_frame_" + str(count) + ".jpeg"
hc.append([join(gesture_frames_path, framename), gesture, frameCount])
if not os.path.exists(framename):
cv2.imwrite(framename, lastFrame)
count += 1
os.chdir(gesture_path)
cap.release()
cv2.destroyAllWindows()
os.chdir(rootPath)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Extract Individual Frames from gesture videos.')
parser.add_argument('gesture_folder', help='Path to folder containing folders of videos of different gestures.')
parser.add_argument('target_folder', help='Path to folder where extracted frames should be kept.')
args = parser.parse_args()
convert(args.gesture_folder, args.target_folder)
This is the link to project's git hub repository.
So I'm relatively new to python but the snippet of code you shared is a function with inputs of gesture_folder and target_folder so with that said you will need to see where the function convert() is called in your overall code and then check what inputs are inside of the function call.
So if it looks like this then replace the paths in the function call
convert("C:\\User\gesturefolder","C:\\User\targetfolder" )
But if it looks like this
convert(gf,tf)
then you will need to work backwards and find where gf and tf are declared and replace the paths there
EDIT:
parser.add_argument('C:\\User\gesturefolder', help='Path to folder containing folders of videos of different gestures.')
parser.add_argument('C:\\User\targetfolder', help='Path to folder where extracted frames should be kept.')
If replacing this with your paths doesnt work then try replacing all backslashes with either \ or /
EDIT2:
So I looked through the Github and it appears the paths are provided when calling the python code
video-to-frame.py [-h] gesture_folder target_folder
Have you tried something like this
gesture_folder="C:\\..." #gesture folder path
target_folder="C:\\..." #target folder path
video-to-frame.py [-h] gesture_folder target_folder
EDIT3:
The last suggestion I can think of is since you are just running it the code directly and not calling it then just define the paths at the beginning of the code between the imports and hc
import cv2
import os
import pickle
from os.path import join, exists
import handsegment as hs
import argparse
from tqdm import tqdm
gesture_folder="C:\\..." #gesture folder path
target_folder="C:\\..." #target folder path
hc = []