Skip to content

Conversation

@ATATC
Copy link
Contributor

@ATATC ATATC commented Oct 24, 2025

See #84.

@ATATC ATATC added this to the 1.1.0 milestone Oct 24, 2025
@ATATC ATATC self-assigned this Oct 24, 2025
@ATATC ATATC added bug Something isn't working todo New task or assignment labels Oct 24, 2025
@ATATC ATATC linked an issue Oct 24, 2025 that may be closed by this pull request
@ATATC
Copy link
Contributor Author

ATATC commented Oct 24, 2025

@perctrix can you check

@perctrix
Copy link
Collaborator

For 3D, that works. For 2D cases, it failed due to SimpleITK limited support for dtypes:
RuntimeError: Exception thrown in SimpleITK ImageFileWriter_Execute PNG supports unsigned char and unsigned short
Solution is adding dtype convert in save_image to convert dtype to torch.uint8. Additionally, only torch.uint8 is appropriate here because other unsigned short (such as torch.uint16, torch.uint32) are limited support by torch and will save unexpected image to file.

@perctrix
Copy link
Collaborator

BTW, I suggest adding os.mkdir() before saving the image. Currently, if the folder does not exist, without making the folder manually (which people tend to forget and hard to understand from the error message), SimpleITK will also raise the error RuntimeError: Exception thrown in SimpleITK ImageFileWriter_Execute: Problem while opening the file.

@ATATC
Copy link
Contributor Author

ATATC commented Oct 24, 2025

I added error handling.

@perctrix
Copy link
Collaborator

Also, dtype not supported is the most important problem here.

@ATATC
Copy link
Contributor Author

ATATC commented Oct 24, 2025

What if the image is float?

@perctrix
Copy link
Collaborator

perctrix commented Oct 24, 2025

Well, just convert to an integer... because for .PNG, SimpleITK only supports 8-bit unsigned integer pixels.

ATATC added 2 commits October 24, 2025 14:04
…across modules for centralized utility management. (#84)
@ATATC
Copy link
Contributor Author

ATATC commented Oct 24, 2025

There is a helper function for it, actually. I have included auto_convert() in save_image(). Does it work now?

@perctrix
Copy link
Collaborator

perctrix commented Oct 24, 2025

rn the auto_convert returns a tensor with dtype torch.int32. In save_image, we have to convert to uint8 manually

@ATATC
Copy link
Contributor Author

ATATC commented Oct 25, 2025

What abt now?

@perctrix
Copy link
Collaborator

It technically works, but the output is still not aligned with our expected visualization result. Currently, we would like the prediction output to look like this:
prediction_0
However, what we actually obtain is:
prediction_0_torch
In the second sample, some skeletal structure is visible, but it remains extremely faint. This is because the model outputs raw logits with varying dynamic ranges (e.g., [-5, 11]), and Normalize(domain=(0, 255), strict=False) adapts the target upper bound to the actual maximum value. When logits max at 11, the output becomes [0, 11] instead of [0, 255], resulting in only 4.3% brightness.
The solution is to use strict=True:

Normalize(domain=(0, 255), strict=True)(image).int()

to force full-range normalization regardless of input dynamic range.

@perctrix
Copy link
Collaborator

Additionally, I tested that if we normalize after sigmoid, we also need strict=True.

@ATATC
Copy link
Contributor Author

ATATC commented Oct 27, 2025

That normalization should be done separately. Some images are intended to have a maximum value that is not 255. We should not narrow that down to a strict range.

@ATATC ATATC merged commit 31cb7e0 into main Oct 27, 2025
3 checks passed
@ATATC ATATC deleted the 84 branch October 27, 2025 22:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working todo New task or assignment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inference failed saving prediction

3 participants