OS function in python to read files - python

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!

Related

convert all img in one pdf .?

I would like to finish my script, I tried a lot to solve but being a beginner failed.
I have a function imageio which takes image from website and after that, i would like resize all images in 63x88 and put all my images in one pdf.
full_path = os.path.join(filePath1, name + ".png")
if os.path.exists(full_path):
number = 1
while True:
full_path = os.path.join(filePath1, name + str(number) + ".png")
if not os.path.exists(full_path):
break
number += 1
imageio.imwrite(full_path, im_padded.astype(np.uint8))
os.chmod(full_path, mode=0o777)
thanks for answer
We (ImageIO) currently don't have a PDF reader/writer. There is a long-standing features request for it, which hasn't been implemented yet because there is currently nobody willing to contribute it.
Regarding the loading of images, we have an example for this in the docs:
import imageio as iio
from pathlib import Path
images = list()
for file in Path("path/to/folder").iterdir():
im = iio.imread(file)
images.append(im)
The caveat is that this particular example assumes that you want to read all images in a folder, and that there is only images in said folder. If either of these cases doesn't apply to you, you can easily customize the snippet.
Regarding the resizing of images, you have several options, and I recommend scikit-image's resize function.
To then get all the images into a PDF, you could have a look at matplotlib, which can generate a figure which you can save as a PDF file. The exact steps to do so will depend on the desired layout of your resulting pdf.

cv2.imread works with one file but not when iterating os.listdir()

I try to import several images to opencv with cv.imread() function.
I think there is a problem with the way I give the path to imread().
With one file it's ok with:
cv.imread('data/img.png')
But within a for loop:
imgs = os.listdir('./data')
targets = []
for img in imgs:
target = cv.imread(img)
targets.append(target)
I keep getting an array full of None values, which means opencv didn't load the file.
print(img) give me an output like ['btn1.png','btn2.png','btn3.png'] which seems fine to me: it's a list of string.
What I am doing wrong here and why did this string is not passed as it is printed to me?
The problem is imgs contains the filename of images but they aren't full file path, so your program cannot find the your image file.
Try to fix your program to be something like
root_dir = './data'
imgs = [os.path.join(root_dir, f) for f in os.listdir(root_dir)]
targets = []
for img in imgs:
target = cv2.imread(img)
targets.append(target)
os.listdir gives the file name, not its path. You need to add the path back in or use a different API that includes the path. glob.glob(os.path.join("path", "*.png")) would do it. But you can also use pathlib
from pathlib import Path
targets = [cv.imread(path) for path in Path("data").glob("*.png")]

Save a picture in wrong folder using opencv

Directory I would need to save to:
DataBase-Faces\name
Directory where the code is saving:
DataBase-Faces
My code:
cv2.imwrite("DataBase-Faces\\"+name+str(frames)+".png",Faceimage)
My program creates a folder with the typed name, I have to record these images in that folder, and the name of each image will be called Nome Typed + (frame number) .png
It looks like you're forgetting to put a directory separator between name and str(frames).
Try
image_path = '\\'.join(['DataBase-Faces', name, str(frames) + '.png'])
cv2.imwrite(image_path, Faceimage)
As a side note, you should not be concatenating paths by hand. Consider looking into the os.path module, which can save you from this sort of headache in the future.
General the Code to save the image is something like that
cv2.imwrite('file.png',img)
For the 'file.png' u want to be
EXAMPLE
name = 'my_photo_album_name'
frames = 500
frame_name = f'{name}\{frames}'
cv2.imwrite(f'DataBase-Faces\{frame_name}.png', img)

In python's unittest, how do I mock a fake folder with fake images inside?

I am trying to create a unit test for a function that reads every image from a folder and saves them in a list.
Here is a simplified version of the function:
def read_images(directory):
image_paths = os.listdir(directory)
images = []
for im in image_paths:
images.append(cv2.imread(os.path.join(directory, im)))
return images
This other question brought me close to the solution, but in my case I want the fake files created to be images (basically, arrays) so I can read them with cv2.imread.
My idea is not having to create any temporary folder and, of course, not having to connect with any external folder or database. Is this possible?
Edit: to be clear, I'd like to not have to create temporary folders, nor temporary image files. I'd like to know if there is a way of telling the program: "There is a folder here, and inside it there are some images/arrays with this shape", but with actually not having to create anything in memory.
If you actually need temporary files, you should check tempfile.
It allows you to create temporary files and directories which provide automatic cleanup, so there are no trash files if you use this while having the opportunity to test what you want.
EDIT
If you don't really want to use tempfiles nor tempfolders, here is another solution concerning your problem:
Generate in-memory image for your test.
from io import BytesIO
from PIL import Image
def create_in_memory_image():
in_memory_file = BytesIO()
image = Image.new('RGBA',
size=(0, 0),
color=(155, 0, 0))
image.save(in_memory_file,
'png')
in_memory_file.name = 'tmp_testing_name.png'
in_memory_file.seek(0)
return in_memory_file
how do I mock a fake folder with fake images inside?
def local_cv2_imread():
# use as a side effect
return 'fakeImg1'
def test_read_images(self):
with mock.patch('os.listdir') as mock_listdir:
with mock.patch('package.module.cv2.imread') as mock_imread:
mock_listdir.return_value = ['fake_path']
mock_imread.side_effect = local_cv2_imread
images = read_images('a_real_path')
self.assertEqual(images, ['fakeImg1']

Chunking a directory and applying image blending using PIL. Can't save images correctly with Python

Sorry for the title... So the goal of this script is to take a folder full on images that are listed in a particular order. Then it chunks the images into groups of 3. From there it takes the 3 images and blends them together using PIL. Now the issue that I have is that the code below does a great job of doing what I want. I can show imgbld2 it'll create 4 images in a temporary folder.
Now my problem is that when I go to save the images using imgbld2.save()it will only save the first created image into 4 image files, instead of 4 created images into 4 separate files.
I can fix this issue by pointing another script to retrieve the images from the temp folder by using glob.glob(). But that would require me to make sure to run the script on a freshly restarted computer but that seems to be too messy for my taste.
Is there a better way to achieve what I'm trying to do? Or there a saving method that I'm missing?
Any help would be appreciated, here is the code:
from PIL import Image
import os.path
import glob
#Lists Directory
Dir = os.listdir('/path/to/Directory/of/Images')
#Glob all jpgs
im = glob.glob( '/path/to/Directory/of/Images/*.jpg')
#sort jpg according to name
imsort = sorted(im)
def chunker(imsort,size = 3):
for i in range(0, len(imsort), size):
yield imsort[i:i + size]
print('what does it look like?')
for j in chunker(imsort):
print(j)
img1 = Image.open(j[0])
img2 = Image.open(j[1])
img3 = Image.open(j[2])
imgbld1 = Image.blend(img1, img2, 0.3)
imgbld2 = Image.blend(imgbld1, img3, 0.3)
imgbld2.show()
imgbld2.save('path/to/new/folder/' + 'blended' , 'JPEG')

Categories