Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

texturize enhance: pic should be PIL Image or ndarray #47

Open
terrainer opened this issue Oct 7, 2023 · 4 comments
Open

texturize enhance: pic should be PIL Image or ndarray #47

terrainer opened this issue Oct 7, 2023 · 4 comments

Comments

@terrainer
Copy link

terrainer commented Oct 7, 2023

Full traceback:
Traceback (most recent call last): File "<frozen runpy>", line 198, in _run_module_as_main File "<frozen runpy>", line 88, in _run_code File "C:\tools\miniconda3\envs\texturize\Scripts\texturize.exe\__main__.py", line 7, in <module> File "C:\tools\miniconda3\envs\texturize\Lib\site-packages\texturize\__main__.py", line 154, in main cmd = commands.Enhance(target_arr, source_arr, zoom=zoom) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\tools\miniconda3\envs\texturize\Lib\site-packages\texturize\commands.py", line 105, in __init__ self.target = load_tensor_from_image(target, device="cpu") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\tools\miniconda3\envs\texturize\Lib\site-packages\texturize\io.py", line 58, in load_tensor_from_image return V.to_tensor(image).unsqueeze(0).to(device, dtype) ^^^^^^^^^^^^^^^^^^ File "C:\tools\miniconda3\envs\texturize\Lib\site-packages\torchvision\transforms\functional.py", line 140, in to_tensor raise TypeError(f"pic should be PIL Image or ndarray. Got {type(pic)}") TypeError: pic should be PIL Image or ndarray. Got <class 'tuple'>

Getting this when trying to use the enhance command with two RGB, 8 bits-per-channel, PNG files. Unsure what I'm doing wrong.
Command used: texturize enhance tests/lowres.png with tests/highres.png --zoom=4

@POD666
Copy link

POD666 commented Jan 28, 2025

Just got the same issue:

$ texturize remake sample.jpg like sample2.jpg --weight 0.5 -o test.jpg
...
pic should be PIL Image or ndarray. Got <class 'tuple'>

@htoyryla
Copy link

htoyryla commented Jan 29, 2025

I get the same error and it persists regardless of which PyTorch & torchvision version is in use.

However, I have used texturize successfully two years ago. I still have the env I used then and it works (texturize version 0.12).

So you could try to install that

pip install texturize==0.12

and see if it works. It is not the latest version though.

@htoyryla
Copy link

htoyryla commented Jan 30, 2025

Seems to me that the errors result as follows

First the source and the target are extracted from the command line here

source_arr, source_props = io.load_tensor_from_files(filename)
target_arr = io.load_tensor_from_files(target) if target else None

using this function

def load_tensor_from_files(glob_pattern, device='cpu', mode=None) -> tuple:
arrays, props = [], []
for filename in sorted(glob.glob(glob_pattern)):
img = load_image_from_file(filename, mode)
arr = load_tensor_from_image(img, device)
arrays.append(arr)
prop = ''.join([s[2] for s in difflib.ndiff(glob_pattern, filename) if s[0]=='+'])
props.append(prop + ":" + str(arr.shape[1]))
assert all(a.shape[2:] == arrays[0].shape[2:] for a in arrays[1:])
return torch.cat(arrays, dim=1), props
which returns a tuple (a tensor, a list of props). For the source, these are saved in separate variables, but the target the tuple is stored.

In Remake

class Remake(Command):
def __init__(self, target, source, weights=[1.0]):
self.source = load_tensor_from_image(source, device="cpu")
self.target = load_tensor_from_image(target, device="cpu")
self.weights = torch.tensor(weights, dtype=torch.float32).view(-1, 1, 1, 1)
then this target is passed here
def load_tensor_from_image(image, device, dtype=torch.float32):
# NOTE: torchvision incorrectly assumes that I;16 means signed, but
# Pillow docs say unsigned.
if isinstance(image, PIL.Image.Image) and image.mode == "I;16":
import numpy
arr = numpy.frombuffer(image.tobytes(), dtype=numpy.uint16)
arr = arr.reshape((image.height, image.width))
assert arr.min() >= 0 and arr.max() < 65536
image = arr.astype(numpy.float32) / 65536.0
if not isinstance(image, torch.Tensor):
return V.to_tensor(image).unsqueeze(0).to(device, dtype)
return image
where it checks if it is a tensor, it is not because it is tuple (tensor, list), and assuming it is a PIL image tries to convert it to a tensor which of course results in an error.

I have not tried to modify the code but a simple solution might be to modify this line

target_arr = io.load_tensor_from_files(target) if target else None

to this

target_arr, _ = io.load_tensor_from_files(target) if target else None

Edits: due to copy-paste errors the links to code were not correct in the original posting, now corrected.

@htoyryla
Copy link

Tried to test the change I proposed but not being familiar with poetry tool did not find a way to run my version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants