Loop through files in list and move specified one (Python) - python

I have this code which show me all the .tif files in a folder I give.
timestr = datetime.now().strftime('%Y%m%d-%H%M%S%f')
ex_area_files = []
tif_files = glob.glob('C:\\Users\\Bob\\Desktop\\Folder\\' + str(timestr) + '\\EXTRACTED\\*.tif')
ex_area_files = [tif_files]
print(ex_area_files)
How can I move some specified ones (to another folder) ? I mean, I want to move all the .tif files which result of width*height is less/more than a certain value.
What I tried was to loop through the array and, after set the codition, move the files. All the result was a loop fail which blocked all the system :)
It follows...
image = cv2.imread('image.jpg')
height = np.size(image, 0)
width = np.size(image, 1)
condition = (height*width) > 9600
How can I also set ex_area_files (my .tif array) as directory of files from which cv2 can read ? And, more imporant, how to set a file at once ?
The files which satisfy the condition (images with values of 320*30px) should be moved to another directory. How to do it after the program decided that the file is ok to be moved ?
Thanks
Tip: this is a next step after this other piece of code: Exclude images of certain dimensions from process (OpenCV, Python)
In this case, take a look at ex_area14.png. I want to move a series of files like that (but in .tif format..)

I recommend using shutil for moving files. To move them You can use shutil.copy() - I Personally use shutil.copy2()
so try something like this:
import shutil
import opencv
for files in ex_area_files:
if files (PLACE YOUR CONDITION HERE):
`shutil.copy('PATH_OF_file', 'PATH_OF_WHERE_TO_DROP')
EDIT:
So i personally like os.walk(), here i'm looping through the files, and if files endswith .tif, I will read the file with imread get the height and width, and check if that condition is met. You'll have to provide where you want to copy the files to. (Take note of .replace() - imread for some reason likes the slashes like / instead of \)
import shutil
import opencv
import os
for root, dirs, files in os.walk(r'FOLDER HERE'):
for file in files:
if file.lower().endswith('.tif'):
image = cv2.imread(root.replace('\\', '/') + '/' +file
height = np.size(image, 0)
width = np.size(image, 1)
if height*width > 9600:
shutil.copy(root.replace('\\', '/') + '/' +file, 'PATH_OF_WHERE_TO_DROP')

Related

OS function in python to read files

I have a folder structure listed like the following
MA/valid/wrist/pa/positive/image2.png
Basically, for each wrist there are multiple pa, and for each pa there is a positive or negative study, and for each study there are up to 3 images in png format.
I have written a code below, but it only goes down to the pa level, it does not load my image files. Any help with loading my image files will be appreciated.
def load(Pic_Dir,Imsize):
data = []
dirs = next(os.walk(Pic_Dir))[1]
for dir_name in dirs:
files = next(os.walk(os.path.join(Pic_Dir, dir_name)))[2]
print("load [", len(files), "] files from [",dir_name,"] " )
for i in range(len(files)):
image_name = files[i]
image_path = os.path.join(Pic_Dir, dir_name, image_name)
label = dir_name
img = cv2.imread(image_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = cv2.resize(img, (Imsize, Imsize))
data.append([np.array(img), label])
return
The function is called with the following line:
data=load("/Users/bond/MA/train/XR_WRIST",244)
I am not sure if I understood your question very well. However, if you need to walk through the directory and process all image file in its sub-directory, I would suggest you write something like this:
def load(root_director,Imsize):
import os
#TODO:You need to figure out how to get a list of this pa.
# Your question is not clear on how to get here
pas =get_list_of_pa()
cases =["positive", "negative"]
for pa in pas:
for case in cases:
in_dir = os.path.join(root_directory, pa, case)
all_images = [f for f in os.listdir(in_dir) if f.endswith('.png')]
for image in all_images:
#Do your processing here
pass
Basically, as you said, if you have many pa (what is pa?) you first need to get a list of all pas and loop through each one to access the list of cases=["positive", "negative]. This is not optimum. There are better ways to go through a directory, e.g., using the path.rglob or os.walk method you used before.
Please note that I am writing this code off the top of my head and did not test it in any way.
As a side note, IMHO, I would refactor your method and call it as follows
def load (director, pa, case):
# Get images for the pa and case
# Process the images
This would potentially reduce its complexity. In fact, to respect the single-responsibility principle (SRP), you probably need to refactor the method much further. For example, you need a method to get all the images of a directory
def get_images (director):
pass
Which returns the list of images (in this case, only .png files). Then, you would need another method that processes the image
def process_image (Imsize):
pass
I hope this helps!

Delete image by size

I have a program that searches for objects based on color position and sharpness. I cut out a 140x140 pixel image of the found objects. But there are some images that are not this size due to some error. And my sharpness determinant always returns those that are smaller in size. My question is how can I iteratively go through a folder and delete only images that are not 140x140 pixels in size.
Check out this tutorial, it helps with the iteration of files in a given directory given an extension (.jpg, .png, etc.)
Find all files in a directory with extension .txt in Python
To actually change the files, I'm not too sure, but probably something like python os.
This is one way among many different ways you can do this. Just make sure you test it before running any batch deletion as this will remove files without cautioning.
import os
import cv2
img = cv2.imread('/absolute/path/to/your/file', cv2.IMREAD_GRAYSCALE)
h, w = img.shape
if(not (h == 140 and w == 140)):
os.remove('/absolute/path/to/your/file')
As for iterating over files in a directory there's already a SO thread that poses multitude of solutions:
How can I iterate over files in a given directory?
import os
import cv2
img = cv2.imread('/yourfile', cv2.IMREAD_GRAYSCALE)
h, w = img.shape
if(not (h == and w == 140)):
os.remove('/absolute/path/to/your/file')

Select only .tif files in scene, Maya-Python

I'm trying to create a small tool where I select all the files (textures) in my scene and apply a specific filter to them.
I get the list of '.fileTextureName' attributes that exist on my scene and I get every .exr and .tif that I have. But I am trying to remove the .exr from my list and only apply the filter only to the .tif.
I haven't find a way to make a list of the attributes or to select just the type of file I want.
Here is just the begining of the script:
import maya.cmds as cmds
allFileNodes = cmds.ls(type="file")
def attrList():
for eachFile in allFileNodes:
currentFile = cmds.getAttr(eachFile + '.fileTextureName')
print currentFile
attrList()
Any help is appreciated!!
If you're simply wanting to filter what to operate on based on its file extension then you can use .endswith to only include tif extensions:
import maya.cmds as cmds
all_file_nodes = cmds.ls(type="file")
for each_file in all_file_nodes:
image_path = cmds.getAttr(each_file + ".fileTextureName") # Get the image's path the file is referencing.
if image_path.lower().endswith(".jpg"): # Only continue if the image ends with `tif`, we include `.lower()` in case the extension is upper case.
print image_path # Only tifs beyond this point, do what you want.

Defining a filename and calling the filename in various loops and functions

In short, I have written a code that opens up a file and does a number of modifications on it. However, I don't want to keep going through my script and renaming all the files when I want to open up a new file.
I'm thinking of setting a variable early on that defines the filename, i.e.
A=filename('png1.png')
B=filename('png2.png')
However, I don't quite know how to implement this. This is my current code:
import os
from os import path
import numpy as np
from PIL import Image
from wordcloud import WordCloud, STOPWORDS
#d=path.dirname(_file_) if "_file_" in locals() else os.getcwd()
os.chdir('C:/Users/Sams PC/Desktop/Word_Cloud_Scripts/Dmitrys Papers/Word_Cloud_Dmitry')
Document=open('Dmitry_all_lower.txt', 'r', encoding='utf-8')
text=Document.read()
heart_mask=np.array(Image.open("**png1.png**"))
print (heart_mask)
split= str('**png1.png**').rsplit('.')
extension=split[len(split)-1]
if extension == "png":
image = Image.open("**png1.png**")
image.convert("RGBA") # Convert this to RGBA if possible
canvas = Image.new('RGBA', image.size, (255,255,255,255)) # Empty canvas colour (r,g,b,a)
canvas.paste(image, mask=image) # Paste the image onto the canvas, using it's alpha channel as mask
#canvas.thumbnail([width, height], Image.ANTIALIAS)
canvas.save('**png2.png**')
from wand.image import Image
with Image(filename='**png2.png**') as img:
img.format='jpeg'
img.save(filename='**png1.jpg**')
from PIL import Image
heart_mask=np.array(Image.open("**png1.jpg**"))
else:
print ('')
print (heart_mask)
stopwords=set(STOPWORDS)
stopwords.update(["will", "us","protein","residue", "interaction","residues","using","proteins","thus","fig"])
wc= WordCloud(stopwords=stopwords, background_color="white",max_words=1000, mask=heart_mask, contour_width=3, contour_color='black')
print ('Generating Word Cloud')
wc.generate(text)
wc.to_file("Dmitry3.png")
import matplotlib.pyplot as plt
plt.figure()
plt.imshow(wc,interpolation="bilinear")
plt.axis("off")
print ('Generation Done')
plt.show()
I've put the entire thing just to see what's going on, but I've bolded (put stars next to), the files I'm trying to modify in my idea. As you can see, I have multiple calls to my file 'png1.png', and I also have calls to save a modified version of that file to 'png2.png' and later a jpeg version of it 'png1.jpg'. I don't want to have to go through my script each time and change each one individually. I was hoping to define them earlier such as A=png1, B=png2, C=jpg1 so that I can replace the calls in my loops with simply A B and C, and if I do choose a new image to upload, I simply change 1 or 2 lines rather than 5 or 6. I.E.
heart_mask=np.array(Image.open("A"))
split= str('A').rsplit('.')
image = Image.open("A")
canvas.save('B')
... so on and so forth
To make your task easier, perhaps you should establish a naming standard defining which files are to be modified, and which ones are already processed. Also, the images you are to process should have a dedicated directory for the purpose.
From what I understand in your code, PNG files are the ones getting processed, while the JPEG files are already done. You can use os.listdir() to traverse a list of files which have a .png extension, something similar to the one below:
for file in os.listdir( "/dedicated_image_dir" ):
if file.endswith(".png"):
# Process your PNG images here
That way, you wouldn't even need to change your code just to accommodate new PNG images with different filenames.

How do I get the face_recognition encoding from many images in a directory and store them in a CSV File?

This is the code I have and it works for single images:
Loading images and apply the encoding
from face_recognition.face_recognition_cli import image_files_in_folder
Image1 = face_recognition.load_image_file("Folder/Image1.jpg")
Image_encoding1 = face_recognition.face_encodings(Image1)
Image2 = face_recognition.load_image_file("Folder/Image2.jpg")
Image_encoding2 = face_recognition.face_encodings(Image2)
Face encodings are stored in the first array, after column_stack we have to resize
Encodings_For_File = np.column_stack(([Image_encoding1[0]],
[Image_encoding2[0]]))
Encodings_For_File.resize((2, 128))
Convert array to pandas dataframe and write to csv
Encodings_For_File_Panda = pd.DataFrame(Encodings_For_File)
Encodings_For_File_Panda.to_csv("Celebrity_Face_Encoding.csv")
How do I loop over the images in 'Folder' and extract the encoding into a csv file? I have to do this with many images and cannot do it manually. I tried several approaches, but none a working for me. Cv2 can be used instead of load_image_file?
Try this
Note: I am assuming you dont need to specify folder path before file name in your command. This code will show you how to iterate over the directory to list files and process them
import os
from face_recognition.face_recognition_cli import image_files_in_folder
my_dir = 'folder/path/' # Folder where all your image files reside. Ensure it ends with '/
encoding_for_file = [] # Create an empty list for saving encoded files
for i in os.listdir(my_dir): # Loop over the folder to list individual files
image = my_dir + i
image = face_recognition.load_image_file(image) # Run your load command
image_encoding = face_recognition.face_encodings(image) # Run your encoding command
encoding_for_file.append(image_encoding[0]) # Append the results to encoding_for_file list
encoding_for_file.resize((2, 128)) # Resize using your command
You can then convert to pandas and export to csv. Let me know how it goes

Categories