Reputation: 821
I am iterating through files in a folder (input) and do some operation and save the results to new files in a new folder (output). However, ending up with this error.
Error
Traceback (most recent call last):
File "mask_class_modifier.py", line 28, in <module>
shutil.copy(x, new_mask_dir)
File "/Users/g/miniconda2/lib/python3.6/shutil.py", line 244, in copy
dst = os.path.join(dst, os.path.basename(src))
File "/Users/g/miniconda2/lib/python3.6/posixpath.py", line 146, in basename
p = os.fspath(p)
TypeError: expected str, bytes or os.PathLike object, not tuple
code
import sys
import os
from PIL import Image
import shutil
import numpy as np
mask_dir = "input/"
new_mask_dir = "output/"
# change the class number of masks in each image
results1 = []
for filename in os.scandir(mask_dir):
if filename.path.endswith(".png"):
image = Image.open(filename.path)
mask = np.array(image)
mask[mask==3] = 50,
mask[mask==4] = 51
results1.append((filename.path, mask))
# copies files with masks to a new directory
for x in results1:
shutil.copy(x, new_mask_dir)
Reproducible code
mask1 = Image.open(urlopen('https://user-images.githubusercontent.com/3885659/78411130-24eee380-75fe-11ea-831c-84ca2eae82ac.png'))
mask2 = Image.open(urlopen('https://user-images.githubusercontent.com/3885659/78411130-24eee380-75fe-11ea-831c-84ca2eae82ac.png'))
mask3 = Image.open(urlopen('https://user-images.githubusercontent.com/3885659/78411130-24eee380-75fe-11ea-831c-84ca2eae82ac.png'))
masks_list = [mask1, mask2, mask3]
new_masks=[]
for x in masks_list:
mask = np.array(x)
mask[mask==3] = 50,
mask[mask==4] = 51
new_masks.append(mask)
Upvotes: 1
Views: 228
Reputation: 2629
I think this is what you're trying to do. You were not saving the original image with the new mask and shutil
does not save the mask to a new file either. append
only adds a value to the end of a list. If you're trying to save the image with the new mask try the code below. In this instance, I've used a file name as a key in a dictionary, but you can just use the original file name.
import sys
import os
from PIL import Image
import shutil
import numpy as np
mask_dir = "input/"
new_mask_dir = "output/"
if not os.path.exists(new_mask_dir):
os.mkdir(new_mask_dir)
for filename in os.scandir(mask_dir):
if filename.path.endswith(".png"):
image = Image.open(filename.path)
mask = np.array(image)
mask[mask == 3] = 50
mask[mask == 4] = 51
masked_img = Image.fromarray(mask)
new_img_path = os.path.join(new_mask_dir, filename.name)
masked_img.save(new_img_path)
Upvotes: 1
Reputation: 700
The problem here is this line results1.append((filename.path, mask))
. The use of double brackets means you are adding a tuple to the list results1
. When you then iterate over that list, x becomes a tuple and the shutil.copy
function cannot take a tuple as it's first parameter.
To fix your error, remove the , mask
in the results1.append
line. You don't need to add the mask to the list, because you aren't using it later. Removing this, stops this being a tuple and means the function will work as expected when copying.
Another solution, allowing you to retain the presence of the mask in the list would be to add [0]
after the x
in the copy function call to specify that you are wanting to use the first item in the tuple (the filepath).
If you want to save the new image instead of making a copy, change the final line to be Image.fromarray(x[1]).save(new_mask_dir+x[0])
, which saves the new image as the new file. When doing this, ensure the results1.append
line is exactly as it was before this answer, when it was giving you an error (it won't anymore)
Upvotes: 2