Hyeonseo Kim
Hyeonseo Kim

Reputation: 344

FileNotFoundError in PIL image with relative path and absoulute path

import PIL.Image as pilimg
import numpy as np

# Read image
im = pilimg.open("../dataset/start.jpg")

# Display image
im.show()

# Fetch image pixel data to numpy array
pix = np.array(im)

Project directory

(I'm no the author of the dataset, so I couldn't upload the whole project file.)

I'm trying to read the image with Pillow and convert it to NumPy array. However, I tried several methods such as using absolute path and methods in PIL image.open() working for some images but not others except method using OpenCV. However, it makes FileNotFound always.

The absolute path of start.jpg is F:\GIST 강의 자료\2021 1학기\EC3202 신호 및 시스템\Programming Assignment\dataset\start.jpg. and I believe the relative path to start.jpg from src/program.py is ../dataset/start.jpg.

I'm using conda 4.10.1 and python 3.8.8 and windows 10.

Upvotes: 2

Views: 3154

Answers (3)

ikram-md
ikram-md

Reputation: 1

Provide the full absolute path to the image. for my case i did the following :

Image.open(f'{os.getcwd()}/{project-name}/{image-file-name}.{file-extension}')

Note that the image file must be in the same folder as your project.

For further details, refer to PIL.open method to understand how the library handles file access.

Upvotes: 0

jupiterbjy
jupiterbjy

Reputation: 3503

Do not rely on os.getcwd for relative path. Reason is shown below.

Instead, use pathlib.Path. For i.e. think of these structure.

x:/
 ├ A
 ┃ ├ 1.png
 ┃ ├ 2.png
 ┃ ├ 3.png
 ┃ ├ 4.png
 ┃ └ 5.png
 ┃
 └ B
   └ script.py

If you want to access reliably from script.py to 1.png, you'd better use __file__ to determine path of the script - as current working directory can differ from actual script location as shown in below example output.

import pathlib
import os

print("Current cwd: ", os.getcwd())

# Get current script's folder
script_location = pathlib.Path(__file__).parent

# get data folder
data_location = script_location.parent / "A"

# single file example
png_file = data_location / "1.png"

# alternatively can iterate thru directory
for file_ in data_location.iterdir():

    # print full path in linux style
    print(f"{file_.absolute().as_posix()}")

(Accessing file in different path in absolute path)

jupiterbjy@NYARUDESK/D: py X:\B\script.py
Current cwd:  D:\
X:/A/1.png
X:/A/2.png
X:/A/3.png
X:/A/4.png
X:/A/5.png


(Change directory)

jupiterbjy@NYARUDESK/D: 
❯ cd x:


(Now use indirect path)

jupiterbjy@NYARUDESK/X: py .\B\script.py
Current cwd:  X:\
X:/A/1.png
X:/A/2.png
X:/A/3.png
X:/A/4.png
X:/A/5.png

See how cwd - current working directory - differ for os.getcwd for each run.

However, no matter where you access that script either by indirectly or directly, outside or inside folder B, you can reliably access files relatively using __file__, .parent and .joinpath methods of pathlib.Path objects.

Check out documents of pathlib here, as I see you're Korean, this is linked to korean document.

Upvotes: 2

user_na
user_na

Reputation: 2273

The paths are relative to the current working directory. If you are unsure what the cwd is, you can find it out by doing:

print(f"Current working dir: {os.getcwd()})

Then you can use os.path.join to concat your relative path from there

os.path.join(os.getcwd(),'dataset/start.jpg')

Upvotes: 2

Related Questions