Unable to append in order - python

import os
train_dir = "/Images/train/"
data = []
for i in os.listdir(train_dir):
path = os.path.join(train_dir, i)
img = cv2.imread(path)
print(i)
data.append(img)
My train directory has 49000 images in order img(1), img(2), ..., img(49000)
I want to append these images in this order only but they are getting appended in a different order (as shown in the image).
Any help?
I want to append them as img(1).png, img(2).png, img(3).png, and so on.

Using the sorted method helped me.
data = []
train_dir = "/Images/train/"
files = os.listdir(train_dir)
files = sorted(files ,key=lambda x: int(os.path.splitext(x)[0]))
for i in (files):
path = os.path.join(train_dir, i)
img = cv2.imread(path)
data.append(img)

So all you want to do is to list the images name in a python list. Which is filenames in my solution. Python list has function called sort() which will sort all the images name. Your new filenames list will be in sorted order relative to your images name that are there inside your directory. So, iterating through the list, you will be getting the sorted images name.
train_dir = "/Images/train/"
filenames = [img for img in os.listdir(train_dir)]
filenames.sort()
data = []
for i in filenames:
path = os.path.join(train_dir, i)
img = cv2.imread(path)
print(i)
data.append(img)

Related

How to load the sequence of image in python? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
import S1-T1-C.00000
Image.open('C:/Users/Vims/Desktop/7th sem/ISA/Lab_1/sequence/sequence')
I have set of image sequence or video. I would like to load in the python code. How can I do it? After that I will do background subtraction of an image.
The sequence of image is from S1-T1-C.00000 to S1-T1-C.00999.
In all situations you need for-loop.
If you don't know names then you can use os.listdir(folder) to get all filenames in folder (you can also use sorted() to have them in correct order) and then you have to read every image separatelly
all_images = []
folder = "C:/folder/with/images"
for filename in sorted(os.listdir(folder)):
full_path = os.path.join(folder, filename)
img = Image.open(full_path)
all_images.append( img )
If you know filenames then you can use string formatting or f-string
all_images = []
folder = "C:/folder/with/images"
for number in range(0, 1_000):
filename = f"S1-T1-C.{number:05}"
full_path = os.path.join(folder, filename)
img = Image.open(full_path)
all_images.append( img )
BTW:
If you have images in many folders then it may need nested for-loops
all_images = []
base_folder = "C:/folder/with/images"
for foldername in os.listdir(base_folder):
folder = os.path.join(base_folder, foldername)
for filename in sorted(os.listdir(folder)):
full_path = os.path.join(folder, filename)
img = Image.open(full_path)
all_images.append( img )
If there can be some other files/folders then every version may need some if/else to filter files/folders
There is also module glob which can use * to match many files/folders
all_filenames = glob.glob("*/S1-T1-C.*")
for filename in all_filenames:
# ... code ...

How to get the pictures in group from excel files

I have tried to extract pictures from excel, but after grouping the text or lines inserted in Excel with pictures, the pictures after the group cannot be completely extracted when extracting the pictures. What should I do?
This is the code I try
import os
import zipfile
import numpy as np
import win32com.client as win32
from PIL import Image
path = 'C:/Users/Peter/Desktop/test/'
count = 1
for file in os.listdir(path):
new_file = file.replace(".xlsx",".zip")
os.rename(os.path.join(path,file),os.path.join(path,new_file))
count+=1
number = 0
list_dir = os.listdir(path)
for i in range(len(list_dir)):
if 'zip' not in list_dir[i]:
list_dir[i] = ''
while '' in list_dir:
list_dir.remove('')
for zip_name in list_dir:
azip = zipfile.ZipFile(path + zip_name)
namelist = (azip.namelist())
for idx in range(0,len(namelist)):
#print(namelist[idx][:9])
if namelist[idx][:9] == 'xl/media/':
img_name = path + str(number)+'.jpg'
f = azip.open(namelist[idx])
img = Image.open(f)
img = img.convert("RGB")
img.save(img_name,"JPEG")
number+=1
f.close()
azip.close()
for file in os.listdir(path):
new_file = file.replace(".zip",".xlsx")
os.rename(os.path.join(path,file),os.path.join(path,new_file))
count+=1
This is my excel file, and the pictures are get from goole for trying, and I added text and arrows to go in.
And this is the pictures I get, there is no text or line in the pictures.
I know very little about Excel, so there may be a much better explanation, but it seems to me that the annotations are stored in an OpenXML file called drawing1.xml inside your XLSX archive.
I can see your two red triangles and the label 40 as annotated below - note that val="ff0000" would correspond to red.

Searching for data in dataframe

Firstly, my apologies if this question is too simple / obvious.
My question is:
I am using nested loops to check whether certain images are listed in a dataframe ('old_df'). If they are present, I add them to an empty list ('new_list').
Is there a faster or more performant way to do this?
images = []
for root, dirs, files in os.walk('/gdrive/MyDrive/CNN_Tute/data/images/'):
for file in files:
images.append(file)
new_list = []
for i in range(len(images)):
for j in range(len(old_df)):
if images[i] == old_df.iloc[j, 0]:
new_list.append(old_df.iloc[j, :])
If want test first column by position:
images = [file for root, dirs, files in os.walk('/gdrive/MyDrive/CNN_Tute/data/images/'
for file in files]
new_list = old_df.iloc[old_df.iloc[:, 0].isin(images).to_numpy(), 0].tolist()
You can achieve this in two lines:
images = [file for _, _, files in os.walk('/gdrive/MyDrive/CNN_Tute/data/images/' for file in files]
new_labels_df = xr_df[xr_df[[0]].isin(images)]

Can I loop through directories and subdirectories and store certain files in an array?

I have one folder that contains many subfolders, and images within those subfolders. I have code that loops through the folders and subfolders and prints out the name of each image one at a time. I want all of these image names to be stored in a single array. How do I get my loop to append each image name to the same array?
I have only seen similar solutions on Linux or Matlab so far, but not on python.
files = []
#r=root, d=directories, f = files
for r, d, f in os.walk(path):
for face_image in f :
if face_image.endswith("g"): #to get all '.jpg' and all '.png' files
print(face_image)
When I run the loop above, I get all ~1000 image names printed. But when I then try and print(face_image) outside of the loop, only the name of the final image in the loop is printed. I now now this is because I have not appended each name to an array, but am not sure how to go about this? Any help would be massively appreciated!
Using pathlib and a recursive glob pattern:
from pathlib import Path
file_types = ("jpg", "png")
file_paths = []
for file_type in file_types:
file_paths.extend(Path(".").glob(f"**/*.{file_type}"))
file_names = [file_path.name for file_path in file_paths]
After your print statement, you can use files.append(face_image) to add the face image to your list. When the loops are done, all valid image names will be in the list for you to use.
I wasn't sure if this was a legit question or not. You need to append the files to the list.
files = []
#r=root, d=directories, f = files
for r, d, f in os.walk(path):
for face_image in f :
if face_image.endswith("g"): #to get all '.jpg' and all '.png' files
print(face_image)
files.append(face_image)
You could try something like this:
files = []
for r, d, f in os.walk(path):
# collect all images
files += [os.path.join(r, file) for file in f]
# filter images
files = [ff for ff in files if ff.endswith('g')]
or a little more compact:
files = []
for r, d, f in os.walk(path):
# collect all images that end with 'g'
files += [os.path.join(r, file) for file in f if file.endswith('g')]

how to save file image as original name

I want to save output images using original name of image.
I try this code, but most cases work well, and a half save other file names. How to do it better?
cropped_images = "GrabCut"
if not os.path.exists(cropped_images):
os.makedirs(cropped_images)
# Load data
filepath = "Data"
images = [cv2.imread(file) for file in glob.glob(filepath + "/*.jpg")]
file_names = []
for filename in os.listdir(filepath):
org_image_name = os.path.splitext(filename)[0]
file_names.append(org_image_name)
for i, image in enumerate(images):
DO SOMETHING...
img_name = file_names[i]
cropped_images_path = os.path.join(cropped_images, img_name + '.jpg')
cv2.imwrite(cropped_images_path, image)
The reason you have the error is because the lists made by glob and os.listdir are not the same, either different files (glob is only getting jpg files and listdir gets everything) or different order, or both. You can change the filenames in a list, orig_files, to make a corresponding list of new filenames, new_files.
It also looks like it makes more sense to just read one image at a time (you only use them one at a time) so I moved that into the loop. You can also use os.path.basename to get the filename, and zip to iterate through multiple lists together.
cropped_images = "GrabCut"
if not os.path.exists(cropped_images):
os.makedirs(cropped_images)
# Load data
filepath = "Data"
orig_files = [file for file in glob.glob(filepath+"/*.jpg")]
new_files = [os.path.join(cropped_images, os.path.basename(f)) for f in orig_files]
for orig_f,new_f in zip(orig_files,new_files):
image = cv2.imread(orig_f)
DO SOMETHING...
cv2.imwrite(new_f, image)

Categories