Skip to content

Add NrrdWriter for multi-channel arrays#779

Closed
markus-hinsche wants to merge 26 commits intoProject-MONAI:mainfrom
rAIdiance:nrrd-writer
Closed

Add NrrdWriter for multi-channel arrays#779
markus-hinsche wants to merge 26 commits intoProject-MONAI:mainfrom
rAIdiance:nrrd-writer

Conversation

@markus-hinsche
Copy link
Copy Markdown
Contributor

@markus-hinsche markus-hinsche commented May 12, 2022

Motivation

The Writer class (in monailabel/transform/writer.py) can't handle multi-channel arrays. The ITK reader and writer both can't handle multi-channel arrays, therefore we want to introduce a new writer that can do this.

Related PRs
This work is related to other works in this area:

Changes

  • Add new function write_seg_nrrd() (similar to write_itk())
  • Add condition when to use nrrd writer
  • Add pynrrd pip dependency to project
  • Add unit test for writing multi-channel data

SachidanandAlle and others added 15 commits May 12, 2022 14:10
* Draft Training workflow for NuClick

Signed-off-by: Sachidanand Alle <[email protected]>

* Sync up changes for nuclick training

Signed-off-by: Sachidanand Alle <[email protected]>

* Fix nuclick training

Signed-off-by: Sachidanand Alle <[email protected]>

* rename transform

Signed-off-by: Sachidanand Alle <[email protected]>

* Sync up changes for nuclick training

Signed-off-by: Sachidanand Alle <[email protected]>

* use monai bunet for nuclick

Signed-off-by: Sachidanand Alle <[email protected]>

* fix log

Signed-off-by: Sachidanand Alle <[email protected]>
Signed-off-by: Markus Hinsche <[email protected]>
Signed-off-by: Markus Hinsche <[email protected]>
Co-authored-by: Janis Vahldiek <[email protected]>
Signed-off-by: Markus Hinsche <[email protected]>
Signed-off-by: Markus Hinsche <[email protected]>
Signed-off-by: Markus Hinsche <[email protected]>
Signed-off-by: Markus Hinsche <[email protected]>
Co-authored-by: Janis Vahldiek <[email protected]>
Signed-off-by: Markus Hinsche <[email protected]>
Signed-off-by: Janis Vahldiek <[email protected]>
Signed-off-by: Markus Hinsche <[email protected]>
write_seg_nrrd() is only needed for 4D multi-channel label arrays. Everything else can be handled by ITK of nifty writer.

Signed-off-by: Janis Vahldiek <[email protected]>
Signed-off-by: Markus Hinsche <[email protected]>
write_seg_nrrd() will only be used for 4D multi-channel label arrays. Thus, removed unnecessary code.

Signed-off-by: Janis Vahldiek <[email protected]>
Signed-off-by: Markus Hinsche <[email protected]>
Signed-off-by: Markus Hinsche <[email protected]>
Signed-off-by: Markus Hinsche
Signed-off-by: Markus Hinsche <[email protected]>
Signed-off-by: Janis Vahldiek <[email protected]>
Signed-off-by: Markus Hinsche <[email protected]>
Signed-off-by: Janis Vahldiek <[email protected]>
Signed-off-by: Markus Hinsche <[email protected]>
Signed-off-by: Markus Hinsche
Signed-off-by: Markus Hinsche <[email protected]>
Signed-off-by: Markus Hinsche <[email protected]>
@SachidanandAlle
Copy link
Copy Markdown
Collaborator

Thanks for raising the PR.. will be look into this asap..

def write_seg_nrrd(
image_np: np.ndarray,
output_file: str,
dtype: type,
Copy link
Copy Markdown
Collaborator

@SachidanandAlle SachidanandAlle May 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

may be u can have default value for dtype

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We tried to make this function's signature similar to the write_itk(). It is probably best to also have a default there as well then, would you agree?


if self.is_multichannel_image(image_np):
if ext != ".seg.nrrd":
logger.debug(
Copy link
Copy Markdown
Collaborator

@SachidanandAlle SachidanandAlle May 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be logger info or warning

return output_file, output_json

def is_multichannel_image(self, image_np):
return len(image_np.shape) == 4 and image_np.shape[-1] > 1
Copy link
Copy Markdown
Collaborator

@SachidanandAlle SachidanandAlle May 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

channel last? normally all images/labels/predictions are processed as channel first in post transform... we better cross check by running some examples e2e..

@diazandr3s can u help to verify this feature...

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to help :)
Should we wait until this PR (Project-MONAI/MONAI#4259) is merged?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can checkout the remote branch and verify..

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Project-MONAI/MONAI#4259 is merged now. I merged upstream/main into this branch

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed this seemed wrong, I updated the code to check the first dimension instead.

FYI:

pynrrd choses the following convention

default index_order='F'
nrrd.writer.write(data)
index_order : {'C', 'F'}, optional
    Specifies the index order used for writing. Either 
    'C' (C-order) 
    	where the dimensions are ordered from
    	slowest-varying to fastest-varying (e.g. (z, y, x)), 
    'F' (Fortran-order)
    	where the dimensions are ordered
    	from fastest-varying to slowest-varying (e.g. (x, y, z)).

We chose 'C' as a default here

torch has the following convention: NxCxHxW

At the moment, in our monailabel-app, we use (5, 4280, 3520, 1) = (channels, width, height, batch)

@diazandr3s
Copy link
Copy Markdown
Collaborator

Motivation

The Writer class (in monailabel/transform/writer.py) can't handle multi-channel arrays. The ITK reader and writer both can't handle multi-channel arrays, therefore we want to introduce a new writer that can do this.

Related PRs This work is related to other works in this area:

* After the NRRD reader, writer also makes sense, see issues:
  
  * see issues: [Implement `NrrdReader` for `nrrd` and `seg.nrrd` files  MONAI#4238](https://github.com/Project-MONAI/MONAI/issues/4238) and [Implement NrrdReader MONAI#4259](https://github.com/Project-MONAI/MONAI/pull/4259)

* `seg.nrrd` tooling with 3D Slicer
  
  * [Add support for .seg.nrrd in UpdateSegmentationMask() of the Slicer extension #768](https://github.com/Project-MONAI/MONAILabel/pull/768)

Changes

* Add new function `write_seg_nrrd()` (similar to `write_itk()`)

* Add condition when to use nrrd writer

* Add `pynrrd` pip dependency to project

* Add unit test for writing multi-channel data

Thanks, @markus-hinsche
This may also help to solve this issue #22

CC @lassoan

markus-hinsche and others added 5 commits May 17, 2022 13:30
* Add Active Learning strategies to DeepEdit

Signed-off-by: Andres Diaz-Pinto <[email protected]>

* Update readme - commands Active Learning strategies

Signed-off-by: Andres Diaz-Pinto <[email protected]>
Signed-off-by: Markus Hinsche <[email protected]>
…I#781)

* Prepare MONAI Label for new monai - DeepEdit transforms

Signed-off-by: Andres Diaz-Pinto <[email protected]>

* Add deprecated messages - DeepEdit transforms - interaction

Signed-off-by: Andres Diaz-Pinto <[email protected]>

Co-authored-by: SACHIDANAND ALLE <[email protected]>
Signed-off-by: Markus Hinsche <[email protected]>
Signed-off-by: SACHIDANAND ALLE <[email protected]>
Signed-off-by: Markus Hinsche <[email protected]>
* Add original labels option Slicer UI

Signed-off-by: Andres Diaz-Pinto <[email protected]>

* Update Slicer module

Signed-off-by: Andres Diaz-Pinto <[email protected]>
Signed-off-by: Markus Hinsche <[email protected]>
@SachidanandAlle
Copy link
Copy Markdown
Collaborator

can you please fix the base branch.. it complains out-of-date and can't be done through UI

@markus-hinsche
Copy link
Copy Markdown
Contributor Author

can you please fix the base branch.. it complains out-of-date and can't be done through UI

I am not sure what the problem is. Feel free to elaborate

Copy link
Copy Markdown
Collaborator

@diazandr3s diazandr3s left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. Looks good to me.

@markus-hinsche
Copy link
Copy Markdown
Contributor Author

Great! Thanks for the feedback

@SachidanandAlle
Copy link
Copy Markdown
Collaborator

Can't merge as it says out of date

@SachidanandAlle
Copy link
Copy Markdown
Collaborator

I see the problem.. u have forked the forked repo..
https://github.com/jlvahldiek/MONAILabel => yours..
this is bit confusing for github itself..

can you please fix the fork and resolve the conflicts correct.. if possible i suggest please fork from the original repo..

@markus-hinsche
Copy link
Copy Markdown
Contributor Author

Closing in favor of #793

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

Successfully merging this pull request may close these issues.

4 participants