Python Pillow error: No such file or directory - python

I have Pillow function for displaying images in Pandas dataframe on Windows machine.It works ok on testing dataset.
Pill function:
from PIL import Image
def get_thumbnail(path):
i = Image.open(path)
print(path)
i.show()
return i
Than I'm using that function to new create new Pandas column that should hold PIL image info. Image is generated based on image URL which is stored in another Pandas column:
adInfoListPD['Ad_thumb']
which looks like this:
> 0
> C:\Users\user\Documents\001ML\willat\Games_Konsolen\03_ps4-pro-500-million-limited-edition-blau-transparent-bundle-29598325900_ps4-pro-500-million-limited-edition-blau-transparent-bundle-295983259__thumb_100x75.jpg
> 1
> C:\Users\user\Documents\001ML\willat\Games_Konsolen\04_playstation-4-20th-anniversary-edition-ungeoeffnet-29586533000_playstation-4-20th-anniversary-edition-ungeoeffnet-295865330__thumb_100x75.jpg
> 2
> C:\Users\user\Documents\001ML\willat\Games_Konsolen\05_playstation-4-20th-anniversary-sammleredition-ovp-29496806400_playstation-4-20th-anniversary-sammleredition-ovp-294968064__thumb_100x75.jpg
> 3
> C:\Users\user\Documents\001ML\willat\Games_Konsolen\07_gratis-versand-alles-zusammen-xxxl-paket-29517022700_gratis-versand-alles-zusammen-xxxl-paket-295170227__thumb_100x75.jpg
> 4
> C:\Users\user\Documents\001ML\willat\Games_Konsolen\08_groesste-ankauf-mit-sofortigem-bargeld-30099513000_groesste-ankauf-mit-sofortigem-bargeld-300995130__thumb_100x75.jpg
> 5
> C:\Users\user\Documents\001ML\willat\Games_Konsolen\09_wir-zahlen-sofort-bargeld-30099285800_wir-zahlen-sofort-bargeld-300992858__thumb_100x75.jpg
And I'm using this line to create column which will hold pill image:
adInfoListPD['image'] = adInfoListPD.Ad_thumb.map(lambda f: get_thumbnail(f)).
I get error:
FileNotFoundError: [Errno 2] No such file or directory:
'C:\\Users\\user\\Documents\\001ML\\willat\\Games_Konsolen\\03_ps4-pro-500-million-limited-edition-blau-transparent-bundle-29598325900_ps4-pro-500-million-limited-edition-blau-transparent-bundle-295983259__thumb_100x75.jpg'
I've double checked paths and they are ok.
I've also read all other posts about python path problems on windows. I think I'm passing path in proper way.
As I said, everything works ok on demo data, but it doesn't work with my data.

Path was the problem in the end.
I used:
os.path.join(dir_base,category_folder,dir_name,file_name_thumb)
to create proper path that would work on all platforms.
I was using that already but I didn't know os.path.join works with filenames as well. So I was adding it manually and therefore omitting "\\" in path between
dir_name and file_name_thumb.
And I also added "\\\\?\\" to path in Pil function:
def get_thumbnail(path):
path = "\\\\?\\"+path
i = Image.open(path)
return i
To fix problems with paths longer than 255 on Windows.
At the same time this is not suppose to mess up path interpretation on Linux machines. But I'm not sure about that...

Related

Image moves or deletes when displaying with PIL

Recently, I have been working on one of my python3 programs and then I wanted to to open a picture. Here is the code that I used to do it:
from PIL import Image
r = Image.open('C:/Users/sudam/OneDrive/Desktop/programming/python/projects/good night app/morning.png' )
r.show()
But as soon as I run this code,the windows photo viewer opens and gives and error saying that the specified file was moved. I tried googling this question but all of the answers I got only worked for python2, but not for python3.
Because you have whitespace in your path you need to use the r"string" format.
Also you need to use:
PIL.ImageShow.show(r)
to show your image.
It's also recommended to check if the file exist before opening any file.
You can do like this:
from pathlib import Path
from PIL import Image, ImageShow
path =r"C:/Users/sudam/OneDrive/Desktop/programming/python/projects/good night app/morning.png"
if Path(path).is_file():
r = Image.open(path)
ImageShow.show(r)
else:
print(f'{path} not exist')

skimage.external.TiffWriter: naming importance

I need to save images as a .tif. I cannot install a new python package (university-controlled computer, with Anaconda), so I decide to use the available Tifffile present in skimage.external.
Here is the trouble:
The following code works nice and saves the 3 channels of my image:
from skimage.external.tifffile import TiffWriter
import numpy as np
path = '26.01.2021 NLFK CPV timeseries A3B10 imaged 07.04.2021/26.01.2021 NLFK CPV timeseries A3B10 imaged 07.04.2021/Processed'
result_img2 = np.zeros((3, 512, 512))
res = (6.006634765625e-08, 6.006634765625e-08)
raw_b = str('abcdefg')
meta = {}
for i, c in enumerate(result_img2):
with TiffWriter(path+'/'+'test_C'+str(i)+'.tif') as tif:
tif.save(np.array(c, dtype='uint8'), resolution=res, description=raw_b, metadata=meta)
But I just cannot keep my images named 'test'!
However, doing like this:
filename = "07.04.2021 NLFK nucleolin r488 A3B10 m546 DAPI mock Preview 2_nucleus1_"
with TiffWriter(path+'/'+filename+str(i)+'.tif') as tif:
tif.save(np.array(c, dtype='uint8'), resolution=res, description=raw_b, metadata=meta)
Results in an Errno 2 error.
I tried to check if this filename contains forbidden characters (from another post):
keepcharacters = (' ','.','_')
filename = "".join(c for c in filename if c.isalnum() or c in keepcharacters).rstrip()
or the encoding filename.encode('utf8') and it also failed (again, Errno 2).
The name indicates the condition of each experiment and changes every time, so I need to save it like that.
After a quick check, I can save it at the root of the .py. But again, I need the file to be saved in their respective folder.
Any idea of where my trouble can be?

List Index out of range.. works on google colab but not on local machine?

I'm trying to recreate this project on my local machine. It's designed to run on Google Colab and I've recreated it there, and it works just fine. I want to try running it on my local machine now, so I installed all the required packages, anaconda, Juypter Notebook etc.
When I come to the part where I process the images:
# Loops through imagepaths to load images and labels into arrays
for path in imagepaths:
img = cv2.imread(path) # Reads image and returns np.array
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Converts into the corret colorspace (GRAY)
img = cv2.resize(img, (320, 120)) # Reduce image size so training can be faster
X.append(img)
#Processing label in image path
category = path.split("/")[3]
label = int(category.split("_")[0][1])
y.append(label)
It throws the following error:
IndexError: list index out of range
The code has not been changed, for the most part, and the dataset is the same. The only difference is I'm running locally vs google colab. I searched online and someone said do len(path) to verify that (in my case) it goes up to [3], which it does (its size 33).
Code has changed here:
I did not use this line, as I'm not using google colab:
from google.colab import files
The "files" is used in this part of code:
# We need to get all the paths for the images to later load them
imagepaths = []
# Go through all the files and subdirectories inside a folder and save path to images inside list
for root, dirs, files in os.walk(".", topdown=False):
for name in files:
path = os.path.join(root, name)
if path.endswith("png"): # We want only the images
imagepaths.append(path)
print(len(imagepaths)) # If > 0, then a PNG image was loaded
On my local machine, I removed the from google.colab... line, and ran everything else normally. The keyword files is used in the code snippet above, however when running it I was thrown no errors. **NOTE len(path) on Jupyter shows 33, len(path) on Google shows 16..?**
Does anyone have any idea what the issue could be? I don't think it came from removing that one line of code. If it did, what do you suggest I do to fix it?
Your local machine is running on Windows while the colab runs on linux and the path separators are different for both.
Now you need to replace
category = path.split("/")[3]
with
category = path.split("\\")[2]
And your code should work.

Convert .IMG (Classic Disk Image) to .PNG/.JPG in Python

I have a dataset of 1,00,000+ .IMG files that I need to convert to .PNG / .JPG format to apply CNN for a simple classification task.
I referred to this answer and the solution works for me partially. What I mean is that some images are not properly converted. The reason for that, according to my understanding is that some images have a Pixel Depth of 16 while some have 8.
for file in fileList:
rawData = open(file, 'rb').read()
size = re.search("(LINES = \d\d\d\d)|(LINES = \d\d\d)", str(rawData))
pixelDepth = re.search("(SAMPLE_BITS = \d\d)|(SAMPLE_BITS = \d)", str(rawData))
size = (str(size)[-6:-2])
pixelDepth = (str(pixelDepth)[-4:-2])
print(int(size))
print(int(pixelDepth))
imgSize = (int(size), int(size))
img = Image.frombytes('L', imgSize, rawData)
img.save(str(file)+'.jpg')
Data Source: NASA Messenger Mission
.IMG files and their corresponding converted .JPG Files
Files with Pixel Depth of 8 are successfully converted:
Files with Pixel Depth of 16 are NOT properly converted:
Please let me know if there's any more information that I should provide.
Hopefully, from my other answer, here, you now have a better understanding of how your files are formatted. So, the code should look something like this:
#!/usr/bin/env python3
import sys
import re
import numpy as np
from PIL import Image
import cv2
rawData = open('EW0220137564B.IMG', 'rb').read()
# File size in bytes
fs = len(rawData)
bitDepth = int(re.search("SAMPLE_BITS\s+=\s+(\d+)",str(rawData)).group(1))
bytespp = int(bitDepth/8)
height = int(re.search("LINES\s+=\s+(\d+)",str(rawData)).group(1))
width = int(re.search("LINE_SAMPLES\s+=\s+(\d+)",str(rawData)).group(1))
print(bitDepth,height,width)
# Offset from start of file to image data - assumes image at tail end of file
offset = fs - (width*height*bytespp)
# Check bitDepth
if bitDepth == 8:
na = np.frombuffer(rawData, offset=offset, dtype=np.uint8).reshape(height,width)
elif bitDepth == 16:
dt = np.dtype(np.uint16)
dt = dt.newbyteorder('>')
na = np.frombuffer(rawData, offset=offset, dtype=dt).reshape(height,width).astype(np.uint8)
else:
print(f'ERROR: Unexpected bit depth: {bitDepth}',file=sys.stderr)
# Save either with PIL
Image.fromarray(na).save('result.jpg')
# Or with OpenCV may be faster
cv2.imwrite('result.jpg', na)
If you have thousands to do, I would recommend GNU Parallel which you can easily install on your Mac with homebrew using:
brew install parallel
You can then change my program above to accept a filename as parameter in-place of the hard-coded filename and the command to get them all done in parallel is:
parallel --dry-run script.py {} ::: *.IMG
For a bit more effort, you can get it done even faster by putting the code above in a function and calling the function for each file specified as a parameter. That way you can avoid starting a new Python interpreter per image and tell GNU Parallel to pass as many files as possible to each invocation of your script like this:
parallel -X --dry-run script.py ::: *.IMG
The structure of the script then looks like this:
def processOne(filename):
open, read, search, extract, save as per my code above
# Main - process all filenames received as parameters
for filename in sys.argv[1:]:
processOne(filename)

Python PIL Paste

I want to paste a bunch of images together with PIL. For some reason, when I run the line blank.paste(img,(i*128,j*128)) I get the following error: ValueError: cannot determine region size; use 4-item box
I tried messing with it and using a tuple with 4 elements like it said (ex. (128,128,128,128)) but it gives me this error: SystemError: new style getargs format but argument is not a tuple
Each image is 128x and has a naming style of "x_y.png" where x and y are from 0 to 39. My code is below.
from PIL import Image
loc = 'top right/'
blank = Image.new("RGB", (6000,6000), "white")
for x in range(40):
for y in reversed(range(40)):
file = str(x)+'_'+str(y)+'.png'
img = open(loc+file)
blank.paste(img,(x*128,y*128))
blank.save('top right.png')
How can I get this to work?
This worked for me, I'm using Odoo v9 and I have pillow 4.0.
I did it steps in my server with ubuntu:
# pip uninstall pillow
# pip install Pillow==3.4.2
# /etc/init.d/odoo restart
You're not loading the image correctly. The built-in function open just opens a new file descriptor. To load an image with PIL, use Image.open instead:
from PIL import Image
im = Image.open("bride.jpg") # open the file and "load" the image in one statement
If you have a reason to use the built-in open, then do something like this:
fin = open("bride.jpg") # open the file
img = Image.open(fin) # "load" the image from the opened file
With PIL, "loading" an image means reading the image header. PIL is lazy, so it doesn't load the actual image data until it needs to.
Also, consider using os.path.join instead of string concatenation.
For me the methods above didn't work.
After checking image.py I found that image.paste(color) needs one more argument like image.paste(color, mask=original). It worked well for me by changing it to this:
image.paste(color, box=(0, 0) + original.size)

Categories