Delete every x file in a directory - Python - python

is there a way to delete all files in a directory but only keep every x files ?
I have a directory which contains images, for a scene taken with a frequency of 10 frames per second. I want to keep every 5th frame.
Example:
if the folder is containing images from 0-10
I want to keep the 5th and the 10th image, and delete the others

If I assume that they are all in a folder and that it contains only those images (and nothing else) then this should work in one complicated line:
import os
[os.remove(os.path.join(folder, img)) for i, img in enumerate(sorted(os.listdir(folder))) if i % 5 != 0]
That should work regardless of how they are named and will only keep every 5th file (change the number 5 if necessary). However, be very careful to give the correct folder and make sure that it doesn't contain anything you don't want deleted. If it does, filter the list first before deleting.
If you're uncomfortable with list comprehensions or with the code being so unreadable (which it kinda is) the longer version of the above is:
import os
image_list = sorted(os.listdir(folder))
for i, img in enumerate(image_list):
if i % 5 != 0:
img_path = os.path.join(folder,img)
os.remove(img_path)
Also, as per your comments, I have added a sorted function to make sure the order is kept alphabetically when removing every 5th element

Related

trying to make a video using moviepy

Having a issue with my code. I'm getting a list index out of range index error
import os
import moviepy.video.io.ImageSequenceClip
image_folder= r'C:\Users\Porsche\OneDrive - Imperial College London\Documents\plates'
fps=1
image_files = [image_folder+'/'+img for img in os.listdir(image_folder) if img.endswith(".jpeg")]
clip = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(image_files, fps=fps)
clip.write_videofile('my_video.mp4')
I'm new to Python and I can't seem to see where the index is and the documentation I found for moviepy was not clear.
the error is on this line
clip = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(image_files, fps=fps)
I just used ImageSequenceClip 5 minutes ago to successfully make a small video so maybe I can assist.
Below are issues related to what I saw in your code and related to problems I had with ImageSequenceClip also. I didn't experience an index error similar to what you've mentioned, but that may be due to your list comprehension line.
A few general suggestions--maybe this will be enough or helpful in other projects you work on:
Careful with your '/' and '\'; keep these uniform to avoid any unwanted issues popping up. I typically use / in all cases for Windows filesystems and it seems to work fine. Also, when manually combining path+filename variables don't forget to include a final '/' at the end of the path variable.
Print out and check the length of the image_files variable you create to make sure you are actually adding the files you wanted and there are no other obvious issues with your list comprehension line.
If you can't locate the issue causing the index error, you can try adding just the folder with the image files only (instead of a list of individual image file locations). In this case, you might need to make a new folder with the files you want included only.
the fps argument was counterintuitive, for me at least. The lower the value, the longer the duration of the individual images in the video.
Finally, the directory you provide to the ImageSequenceClip function will sort the files in alphanumeric order based on the filenames. Keep this in mind as, for example, a1, a2, a11 will be reordered into a1, a11, a2.

How to find objects in floor plan image in Tkinter python through svg file?

I have a vectorized floorplan image. I want to identify the objects in the image through the vector data in the SVG file of that image. The SVG code does not have any close points(z) in between them. So I am unable to understand when does the point moves to the other object? Can somebody help me, please?
I have very little knowledge about these SVG files and using them in Tkinter. So please somebody help me or suggest me what can I do?
This is the vector data of the image.
vector data of the image
use in conjunction with SO floorplan question.
Jump to z_final_floorplan.svg for final file.
A
Create 4 files:
w_original_floorplan.svg
x_rough_static_floorplan.svg
y_rough_live_floorplan.svg
z_final_floorplan.svg
w_original_floorplan.svg and x_rough_static_floorplan.svg are identical apart from filename.
y_rough_live_floorplan.svg and z_final_floorplan.svg are empty; to be populated.
Copy x_rough_static_floorplan.svg to y_rough_live_floorplan.svg.
Open y_rough_live_floorplan.svg on browser using server.
x_rough_static_floorplan.svg find all M and replace with two newlines / symbol M (case sensitive). shift + enter shift + enter /M
B
[this section takes the time]
Take away 1st '/' in path in y_rough_live_floorplan.svg [shows blackout_floorplan]
Label x_rough_static_floorplan.svg code section blackout_floorplan where code is.
(this file is used as rough-work, so being xml / svg valid is irrelevant)
In y_rough_live_floorplan.svg find next '/' and delete it [shows floorplan_top_left_whiteout]
Label x_rough_static_floorplan.svg code section floorplan_top_left_whiteout where code is.
Have x_rough_static_floorplan.svg and y_rough_live_floorplan.svg open in 2 windows, will be going back and forth to each of them. Keep repeating until at end.
(hint: find tool seems to be on switching from files in vscode, so you can use find / and next one cmd + g easily) Maybe handy to have a paper printout of original svg as reference and label the names of objects you create e.g.bath, sink, table, as you go along (don’t be fooled by this, one table is 'table'. Is 2nd chair chair2, chair_2, chair_two etc.?) etc..
C
Reorder the whole labels and corresponding code in path x_rough_static_floorplan.svg so the labels are ordered next to each other, but in the order they are found in the path:
e.g.
…
floorplan
bath
sink
table_chairs
sofa
…
Use the 'find' tool here. This process, itself will require a temp file to copy and paste to rather than reorder within the file working on. And rewrite temp to file working on. Might be good idea to create checklist of objects and cross-off as done.
E.g. floorplan, bath, table_chairs, sink…
D
Create path elements from your grouped objects, putting each id as id=“floorplan_main”, id=“bath”, id=“sink” etc.. etc..
Bear in mind, the data of how this is drawn is really, really bad. Really they should be drawn with rect elements for a rectangle when possible and a lot of the path data is very unnecessary, but that’s obviously how the application generates the svg.

Selecting multiple files for input and getting respective output

So I have this bit of code, which clips out a shapefile of a tree out of a Lidar Pointcloud. When doing this for a single shapefile it works well.
What I want to do: I have 180 individual tree shapefiles and want to clip every file out of the same pointcloud and save it as a individual .las file.
So in the end I should have 180 .las files. E.g. Input_shp: Tree11.shp -> Output_las: Tree11.las
I am sure that there is a way to do all of this at once. I just dont know how to select all shapefiles and save the output to 180 individual .las files.
Im really new to Python and any help would be appreciated.
I already tried to get this with placeholders (.format()) but couldnt really get anywhere.
from WBT.whitebox_tools import WhiteboxTools
wbt = WhiteboxTools()
wbt.work_dir = "/home/david/Documents/Masterarbeit/Pycrown/Individual Trees/"
wbt.clip_lidar_to_polygon(i="Pointcloud_to_clip.las", polygons="tree_11.shp", output="Tree11.las")
I don't have the plugin you are using, but you may be looking for this code snippet:
from WBT.whitebox_tools import WhiteboxTools
wbt = WhiteboxTools()
workDir = "/home/david/Documents/Masterarbeit/Pycrown/Individual Trees/"
wbt.work_dir = workDir
# If you want to select all the files in your work dir you can use the following.
# though you may need to make it absolute, depending on where you run this:
filesInFolder = os.listDir(workDir)
numberOfShapeFiles = len([_ for _ in filesInFolder if _.endswith('.shp')])
# assume shape files start at 0 and end at n-1
# loop over all your shape files.
for fileNumber in range(numberOfShapeFiles):
wbt.clip_lidar_to_polygon(
i="Pointcloud_to_clip.las",
polygons=f"tree_{fileNumber}.shp",
output=f"Tree{fileNumber}.las"
)
This makes use of python format string templates.
Along with the os.listdir function.

How to pick random photo from folder

Lets assume that I have a folder.
The folder contains photos.
I want to pick a random one and, lets say, use different effects on them with pillow, the PIL fork.
How to?
Perhaps something like:
Get a list of the images in the folder.
Get the count of images in
that list.
Generate a random number that falls in the range of your
image count.
Load the image from the list that matches your random
number.
Since you didn't specify a specific language or runtime environment, I've just generalized a possible way of doing this.
Something like:
import random, glob
picture_files = glob.glob(picture_folder + '*.jpg')
random_picture = random.choice( picture_files)
# do something with random_picture

Renaming image files if statement is false

So explained briefly I have a folder where I put some images into. The name of the images are integers, so for example I could have 5 images with the names 567.jpg, 568.jpg, 569.jpg, 570.jpg, and 571.jpg. The integer numbers are random, however, they always come in a sequence like above, i.e. increasing by one for every image.
So what I want to do is to go through the images in this folder and look at the image size. If the width of an image is under 600px (as an example) I want to delete this image and move on to the next image. Now, if this image is then above 600px it should be renamed such as it follows the sequence.
So in principle what should happen is:
345.jpg --> Over 600px --> Nothing happens
346-jpg --> Under 600px --> Gets deleted
347.jph --> Over 600px --> Gets renamed to 346.jpg (to follow the 1 step sequence)
And so on...
I have tried with the following code:
import os
from PIL import Image
img_dir_path = "\"
pic_list = range(567,572,1)
for image in pic_list:
img = Image.open("{}/{}.jpg".format(img_dir_path, image))
if img.size[0] < 600:
os.remove("{}/{}.jpg".format(img_dir_path, image))
else:
if os.path.isfile("{}/{}.jpg".format(img_dir_path, int(image)-1)) == False:
os.rename('{}/{}.jpg'.format(img_dir_path, int(image)), '{}/{}.jpg'.format(img_dir_path, int(image)-1))
else:
print "No worries"
However, when doing so I get the follow error:
WindowsError: [Error 32] The process cannot access the file because it is being used by another process
For the rename process that it...
I know this is some sloppy code, but I'm not a Python expert yet, so I usually just make it work first, and then tweak.
In addition, another problem that arises is that when checking if the entry before the true first entry exists / is false, it always is false now since there of course is nothing before the first image. Therefore, the image with the first name in the list should of course not be renamed. However, since I couldn't even get this to work, I wasn't going to try to fix that.
Do close the image which is opened before renaming img = Image.open("{}/{}.jpg".format(img_dir_path, image))
Image.close()
before rename

Categories