Skip to content
This repository was archived by the owner on Mar 17, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
b07dce8
Ticket #346: refactoring of ImageReader, ImageSetsPartitioner, and ag…
May 16, 2019
e57c90a
Ticket #346: Update of preprocessor layer API to accommodate abstract…
May 16, 2019
a851473
Ticket #346: Update of I/O API
May 16, 2019
0897560
Ticket #346: Update of I/O API
May 16, 2019
1d807b7
Ticket #346: Update of I/O API
May 16, 2019
d4bbd36
Ticket #346: generator-based access to training images during histogr…
May 16, 2019
975b639
Ticket #124: Introduction of a module-wrapper for NiftyNet applications
May 16, 2019
ae159ab
Ticket #124: Unit test for application module wrapper
May 16, 2019
bd65b8e
Ticket #124: Demo of apps-as-modules feature
May 16, 2019
abfb0ee
Reconciled ticket #124 with latest dev changes.
May 16, 2019
700d4e4
Ticket #124: obsolete module; replaced by BaseImageSource and FileIma…
May 16, 2019
cbcea7b
Ticket #346: removed unit tests for obsolete modules
May 16, 2019
0d075c3
linting io folder
wyli May 17, 2019
0b17535
fixes tf logger
wyli May 21, 2019
00e86c7
fixes image source properties
wyli May 21, 2019
1f09e35
deprecated test_session
wyli May 21, 2019
7de0374
deprecated to_int32
wyli May 21, 2019
b3a3cc9
fixes properties
wyli May 21, 2019
47c1aee
optimise image source interfaces
wyli May 21, 2019
f08f962
fixes functions
wyli May 21, 2019
4b2306b
resume previous reader interface usages
wyli May 26, 2019
f6950f1
Revert "deprecated test_session"
wyli May 26, 2019
8b4b5f0
fixes reader init
wyli May 26, 2019
0a1317f
new partitioner interfaces
wyli May 27, 2019
d729914
remove old parititioners
wyli May 27, 2019
d85bd8d
fixes paritioner unit tests
wyli May 27, 2019
87e29a8
fixes tests
wyli May 29, 2019
bb6f12f
fixes temp dir
wyli Jun 2, 2019
728739a
Merge branch 'dev' into 124-apps-as-modules
ericspod Jun 4, 2019
9f40024
Merge branch '124-apps-as-modules' of https://github.com/NifTK/NiftyN…
wyli Jun 4, 2019
afc2c30
Merge branch 'dev' into 124-apps-as-modules
wyli Aug 5, 2019
62ff840
fixes partitioner
wyli Aug 26, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions demos/applications_as_modules/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Using NiftyNet Applications as Modules in 3rd-Party Code

This simple demo shows the use of NiftyNet applications in 3rd-party code via niftynet.application.application_module_wrapper.ApplicationModuleWrapper.
The code accompanying its brief explanation is contained in `module_app.py` that builds on the unet_histology demo. The input images are assumed to be RGB bitmaps while the label images are assumed to be binary and supplied in nii.gz format.


## Model Configuration

Models driven through a app-module are configured via ini files, the same as when using `net_run`. The only difference in terms of configuration format is that file-path specification for input data is no longer required, i.e., `path_to_search`, `filename_contains`, etc.


## I/O Setup

When using a NiftyNet application as a module, input and output of images is done in-memory and asynchronously via callback functions. These callback functions are installed via the `set_input_callback` method, in the case of input images, and the `set_output_callback` method, in the case of the output of inferred images.
Input callbacks essentially replace the input file-path specifications, so one callback for every image type used by the application must be provided. In addition to these callback functions, the total number of subjects in the data set must be specified through the `set_num_subjects` method.


## Running Applications

Before an app can be executed, the type of action (train, infer, evaluate), must be specified through the `set_action` method, and the application initialised via `initialise_application`. Finally, the actual execution is done through the `run` method.
58 changes: 58 additions & 0 deletions demos/applications_as_modules/config.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
############################ Input Configuration
[slice]
interp_order = 1
spatial_window_size = (400, 400)

[label]
interp_order = 0
spatial_window_size = (228, 228)

############################## System Configuration
[SYSTEM]
cuda_devices = ""
num_threads = 1
num_gpus = 1
model_dir = ./models/unet_module_test
queue_length = 36

[NETWORK]
name = unet_2d
batch_size = 5
volume_padding_size = 92, 92, 0
window_sampling = balanced
whitening = True

[TRAINING]
sample_per_volume = 1
lr = 0.01
starting_iter = 0
save_every_n = 100
tensorboard_every_n = 10
max_iter = 2501
loss_type = DicePlusXEnt
random_flipping_axes = (0, 1)
validation_every_n = 10
exclude_fraction_for_validation = 0.2
exclude_fraction_for_inference = 0.05

[INFERENCE]
border = (92, 92)
inference_iter = 403
output_interp_order = 0
spatial_window_size = (400, 400)
save_seg_dir = output/
dataset_to_infer = inference

[EVALUATION]
save_csv_dir = ./eval.csv
evaluations = dice
evaluation_units = label

############################ Application Configuration
[SEGMENTATION]
image = slice
label = label
sampler = label
label_normalisation = False
output_prob = False
num_classes = 2
75 changes: 75 additions & 0 deletions demos/applications_as_modules/module_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from pathlib import Path

import nibabel as nib
import skimage.io as skio

from niftynet.application.application_module_wrapper import \
SegmentationApplicationModule

IMAGES = []
LABELS = []


def get_image(idx):
return skio.imread(IMAGES[idx])


def get_labels(idx):
return nib.load(LABELS[idx]).get_data()


def output_image(img_out, sub, img_in):
print("Rec'd", sub, ':', img_out)


def setup_images(args):
global IMAGES
global LABELS

img_paths = [str(path) for path in Path(args.image_directory).glob('*.bmp')]
img_paths = sorted(img_paths)

IMAGES = []
LABELS = []
for img_path in img_paths:
lab_path = Path(img_path).name.replace('.bmp', '_anno.nii.gz')
lab_path = Path(args.labels_directory)/lab_path

if lab_path.is_file():
img = skio.imread(img_path)
lab = nib.load(str(lab_path)).get_data()

if img.shape[:2] == lab.shape[:2]:
IMAGES.append(img_path)
LABELS.append(str(lab_path))
else:
print('Inconsistent shapes: %s' % Path(img_path).name)
else:
print('No labels: %s' % Path(img_path).name)


def main(args):
setup_images(args)

module = SegmentationApplicationModule(args.model_file)

module.set_input_callback('slice', get_image, do_reshape_rgb=True)\
.set_input_callback('label', get_labels, do_reshape_nd=True)\
.set_output_callback(output_image)\
.set_num_subjects(len(IMAGES))\
.set_action(args.action)\
.initialise_application()\
.run()


if __name__ == '__main__':
import argparse as ap

parser = ap.ArgumentParser(description='App-as-a-Module test script')

parser.add_argument('model_file', help='Model config.ini')
parser.add_argument('image_directory', help='Input image directory')
parser.add_argument('labels_directory', help='Target label directory')
parser.add_argument('action', help='NiftyNet action')

main(parser.parse_args())
Loading