Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Istvan N. Huszar, MD
tirl
Commits
fa6d0484
Commit
fa6d0484
authored
Jun 24, 2020
by
inhuszar
Browse files
Updated histology_to_block with the library functions.
parent
17f40a8c
Changes
15
Expand all
Hide whitespace changes
Inline
Side-by-side
setup.py
View file @
fa6d0484
...
...
@@ -80,5 +80,6 @@ setup(name="tirl",
"tirl/transformations/linear"
,
"tirl/transformations/nonlinear"
,
"tirl/usermodules"
],
scripts
=
[
"tirl/tirl"
]
scripts
=
[
"tirl/tirl"
,
"tirl/tirlvision/sliceview.py"
]
)
tests/resources/params.p
View file @
fa6d0484
No preview for this file type
tests/resources/params.pg
View file @
fa6d0484
No preview for this file type
tests/resources/tirlfiles/test.timg
View file @
fa6d0484
No preview for this file type
tirl/scripts/mnd/__init__.py
View file @
fa6d0484
...
...
@@ -29,6 +29,6 @@ The package includes the following modules:
"""
from
tirl.scripts.mnd
import
i
o
from
tirl.scripts.mnd
import
i
nout
from
tirl.scripts.mnd
import
image
from
tirl.scripts.mnd
import
general
\ No newline at end of file
tirl/scripts/mnd/config/cnf_histology_to_block.json
View file @
fa6d0484
...
...
@@ -5,47 +5,54 @@
"author"
:
"Istvan N Huszar"
},
"general"
:
{
"name"
:
"histology_to_block"
,
"direction"
:
"h2b"
,
"system"
:
"linux"
,
"verbosity"
:
"debug"
,
"logfile"
:
null
,
"outdir"
:
"/
Users/inhuszar
/temp/histo_to_block/4La/reg
_svs_automask
"
,
"out
put
dir"
:
"/
mnt/rio
/temp/
histreg/
histo_to_block/4La/reg"
,
"stages"
:
[
"rotation"
,
"rigid"
,
"affine"
,
"nonlinear"
],
"warnings"
:
false
},
"histology"
:
{
"file"
:
"/Users/inhuszar/temp/histo_to_block/4La/NP140-14-4La-2-PLP.svs"
,
"alternative"
:
null
,
"file"
:
"/mnt/rio/temp/histreg/histo_to_block/4La/NP140-14-4La-2-PLP.svs"
,
"storage"
:
"mem"
,
"dtype"
:
"<f4"
,
"resolution"
:
0.008
,
"mask"
:
{
"file"
:
null
,
"
function"
:
null
,
"
normalise"
:
false
},
"
automask
"
:
{
"
thr"
:
0
,
"uthr"
:
1
"
normalise"
:
true
,
"
function"
:
"labkmeans"
,
"automask"
:
{
"
thr
"
:
0
,
"u
thr"
:
1
}
},
"resolution"
:
0.008
,
"preview"
:
false
,
"actions"
:
[
"resample_histology"
,
"labkmeans"
,
"histology_preproc"
]
"export"
:
true
,
"snapshot"
:
true
},
"block"
:
{
"file"
:
"/
Users/inhuszar/temp
/histo_to_block/4La/block_4La_sup_seg.tif"
,
"file"
:
"/
mnt/rio/temp/histreg
/histo_to_block/4La/block_4La_sup_seg.tif"
,
"storage"
:
"mem"
,
"dtype"
:
"<f4"
,
"resolution"
:
0.050
,
"mask"
:
{
"file"
:
null
,
"normalise"
:
true
,
"function"
:
null
,
"normalise"
:
false
},
"automask"
:
{
"thr"
:
0
,
"uthr"
:
1
"automask"
:
{
"thr"
:
0
,
"uthr"
:
1
}
},
"resolution"
:
0.050
,
"preview"
:
false
,
"actions"
:
[
"block_preproc"
]
"export"
:
false
,
"snapshot"
:
false
},
"preprocessing"
:
{
"histology"
:
[
"match_block_resolution"
,
"histology_preprocessing"
],
"block"
:
[
"block_preprocessing"
]
},
"regparams"
:
{
"init"
:
{
...
...
@@ -96,7 +103,7 @@
"scaling"
:
[
20
,
10
,
5
,
2
],
"smoothing"
:
[
0
,
0
,
0
,
0
],
"xtol_rel"
:
0.01
,
"xtol_abs"
:
[
0.001
,
0.
00
1
,
0.1
,
0.
00
1
,
0.001
,
0.1
],
"xtol_abs"
:
[
0.001
,
0.1
,
0.1
,
0.1
,
0.001
,
0.1
],
"opt_step"
:
[
0.01
,
0.01
,
1
,
0.01
,
0.01
,
1
],
"visualise"
:
false
},
...
...
tirl/scripts/mnd/general.py
View file @
fa6d0484
...
...
@@ -159,14 +159,14 @@ def run_stage(target, source, stage_no, counter, scope, config):
# Export stage result as TImage
ext
=
ts
.
EXTENSIONS
[
"TImage"
]
scr
.
i
o
.
export
(
target
,
q
.
export
.
timage
,
default
=
os
.
path
.
join
(
scr
.
i
nout
.
export
(
target
,
q
.
export
.
timage
,
default
=
os
.
path
.
join
(
p
.
general
.
outputdir
,
f
"
{
counter
}
_stage
{
stage_no
}
.
{
ext
}
"
))
# Create snapshot showing end-stage alignment
snpfile
=
os
.
path
.
join
(
p
.
general
.
outputdir
,
f
"
{
counter
}
_stage
{
stage_no
}
.
{
SNAPSHOT_EXT
}
"
)
scr
.
i
o
.
snapshot
(
source
.
evaluate
(
target
.
domain
),
q
.
export
.
snapshot
,
default
=
snpfile
)
scr
.
i
nout
.
snapshot
(
source
.
evaluate
(
target
.
domain
),
q
.
export
.
snapshot
,
default
=
snpfile
)
# Save mask if requested
if
target
.
tmask
()
is
not
None
:
...
...
@@ -175,14 +175,14 @@ def run_stage(target, source, stage_no, counter, scope, config):
targetmaskfile
=
os
.
path
.
join
(
p
.
general
.
outputdir
,
f
"
{
counter
}
_stage
{
stage_no
}
_targetmask.
{
SNAPSHOT_EXT
}
"
)
scr
.
i
o
.
snapshot
(
mask
,
q
.
export
.
target_mask
,
default
=
targetmaskfile
)
scr
.
i
nout
.
snapshot
(
mask
,
q
.
export
.
target_mask
,
default
=
targetmaskfile
)
if
source
.
tmask
()
is
not
None
:
from
tirl.timage
import
TImage
mask
=
TImage
.
fromTField
(
target
.
tmask
())
sourcemaskfile
=
os
.
path
.
join
(
p
.
general
.
outputdir
,
f
"
{
counter
}
_stage
{
stage_no
}
_sourcemask.
{
SNAPSHOT_EXT
}
"
)
scr
.
i
o
.
snapshot
(
mask
,
q
.
export
.
source_mask
,
default
=
sourcemaskfile
)
scr
.
i
nout
.
snapshot
(
mask
,
q
.
export
.
source_mask
,
default
=
sourcemaskfile
)
# Visualise end-stage alignment
if
q
.
visualise
:
...
...
tirl/scripts/mnd/histology_to_block.py
View file @
fa6d0484
This diff is collapsed.
Click to expand it.
tirl/scripts/mnd/image.py
View file @
fa6d0484
...
...
@@ -171,6 +171,37 @@ def perform_image_operations(img, *actions, scope=None, other=None):
return
lastimg
def
flip_x
(
img
,
**
kwargs
):
"""
Flips the image along the vertical axis.
"""
img
.
data
[...]
=
img
.
data
[::
-
1
,
...]
if
img
.
tmask
()
is
not
None
:
img
.
mask
[...]
=
img
.
mask
[::
-
1
]
def
flip_y
(
img
,
**
kwargs
):
"""
Flips the image along the horizontal axis.
"""
img
.
data
[...]
=
img
.
data
[:,
::
-
1
,
...]
if
img
.
tmask
()
is
not
None
:
img
.
mask
[...]
=
img
.
mask
[:,
::
-
1
]
def
rgb2yiq
(
timg
):
"""
Convert RGB to YIQ, or leave as grayscale.
"""
from
tirl.operations.tensor
import
TensorOperator
if
timg
.
tsize
>=
3
:
mat
=
np
.
asarray
([[
0.299
,
0.587
,
0.114
],
[
0.5959
,
-
0.2746
,
-
0.3213
],
[
0.2115
,
-
0.5227
,
0.3112
]])
return
TensorOperator
(
lambda
t
:
np
.
einsum
(
"ij,...j"
,
mat
,
t
))(
timg
)
else
:
return
timg
\ No newline at end of file
tirl/scripts/mnd/i
o
.py
→
tirl/scripts/mnd/i
nout
.py
View file @
fa6d0484
...
...
@@ -135,6 +135,87 @@ def snapshot(timg, exportattr, default=None):
raise
TypeError
(
f
"Invalid export attribute:
{
exportattr
}
"
)
def
load_histology
(
**
imageinputmodule
):
"""
Loads histology slide from file as TImage.
:param q: configurations related to the histology input
:type q: AttrMap
"""
# Inintialise import parameters
q
=
DEFAULT_IMAGEINPUT_MODULE
.
copy
()
q
.
update
(
imageinputmodule
)
q
=
AttrMap
(
q
)
import
os
from
tirl.timage
import
TImage
# Load image
if
q
.
file
is
None
:
raise
FileNotFoundError
(
"No histology image file was specified."
)
elif
isinstance
(
q
.
file
,
str
):
if
not
os
.
path
.
isfile
(
q
.
file
):
raise
FileNotFoundError
(
f
"Histology image file does not exist:
{
q
.
file
}
"
)
if
q
.
file
.
lower
().
endswith
(
(
ts
.
EXTENSIONS
[
"TImage"
],
ts
.
EXTENSIONS
[
"TIRLObject"
])):
img
=
load_timage
(
q
.
file
)
logger
.
info
(
f
"Loaded histology image from
{
q
.
file
}
:
{
img
}
"
)
return
img
elif
q
.
file
.
lower
().
endswith
(
".svs"
):
import
tirl.loader
img
=
TImage
.
fromfile
(
q
.
file
,
storage
=
q
.
storage
,
dtype
=
q
.
dtype
,
loader
=
tirl
.
loader
.
OpenSlideLoader
,
loader_kwargs
=
{
"level"
:
2
})
logger
.
info
(
f
"Loaded histology image from
{
q
.
file
}
:
{
img
}
"
)
else
:
try
:
img
=
TImage
.
fromfile
(
q
.
file
,
storage
=
q
.
storage
,
dtype
=
q
.
dtype
)
logger
.
info
(
f
"Loaded histology image from
{
q
.
file
}
:
{
img
}
"
)
except
Exception
as
exc
:
logger
.
error
(
exc
.
args
)
logger
.
error
(
"Error while trying to load {}."
)
raise
else
:
raise
TypeError
(
f
"Invalid image file specification:
{
q
.
file
}
"
)
# ------------------------------------------------------------------------ #
# The operations below are only carried out if the image was loaded from
# an "ordinary" image file, not a TImage file.
# ------------------------------------------------------------------------ #
# Set resolution based on user input
img
.
resolution
=
q
.
resolution
logger
.
info
(
f
"Pixel size of the histology image was set per user "
f
"specification to
{
q
.
resolution
}
[a.u./px]."
)
# Set mask
from
tirl.scripts.mnd.image
import
set_mask
set_mask
(
img
,
scope
=
dict
(
q
).
get
(
"scope"
,
globals
()),
**
q
.
mask
)
# Perform operations
from
tirl.scripts.mnd.image
import
perform_image_operations
perform_image_operations
(
img
,
*
q
.
actions
,
scope
=
dict
(
q
).
get
(
"scope"
,
globals
()),
other
=
None
)
# Preview
if
q
.
preview
is
True
:
img
.
preview
()
# Export
export
(
img
,
q
.
export
,
default
=
None
)
# Snapshot
snapshot
(
img
,
q
.
snapshot
,
default
=
None
)
return
img
def
load_image
(
**
imageinputmodule
):
"""
Loads 2D image as a TImage. If the input is a TImage file, it is loaded as
...
...
@@ -178,7 +259,7 @@ def load_image(**imageinputmodule):
raise
else
:
raise
TypeError
(
f
"Invalid
volum
e file specification:
{
q
.
file
}
"
)
raise
TypeError
(
f
"Invalid
imag
e file specification:
{
q
.
file
}
"
)
# ------------------------------------------------------------------------ #
# The operations below are only carried out if the image was loaded from
...
...
tirl/scripts/mnd/slice_to_volume.py
View file @
fa6d0484
...
...
@@ -126,11 +126,11 @@ def run(cnf=None, **options):
if
p
.
slice
.
export
is
True
:
ext
=
ts
.
EXTENSIONS
[
"TImage"
]
p
.
slice
.
export
=
os
.
path
.
join
(
p
.
general
.
outputdir
,
f
"slice.
{
ext
}
"
)
slice_
=
scr
.
i
o
.
load_image
(
**
p
.
slice
)
slice_
=
scr
.
i
nout
.
load_image
(
**
p
.
slice
)
if
p
.
volume
.
export
is
True
:
ext
=
ts
.
EXTENSIONS
[
"TImage"
]
p
.
volume
.
export
=
os
.
path
.
join
(
p
.
general
.
outputdir
,
f
"volume.
{
ext
}
"
)
volume
=
scr
.
i
o
.
load_volume
(
**
p
.
volume
)
volume
=
scr
.
i
nout
.
load_volume
(
**
p
.
volume
)
# Having loaded both images, perform actions on the brain slice photo prior
# to registration, unless it was loaded from an alternative source.
...
...
tirl/tirl
View file @
fa6d0484
...
...
@@ -25,6 +25,7 @@ Part of the FMRIB Software Library (FSL)
Author: Istvan N. Huszar
Available options:
home displays the installation directory
version displays the library version
config [text editor] modify library-wide constants
info <file> display information about a TIRL file
...
...
@@ -56,6 +57,15 @@ def version(*args):
print(tirl.__version__)
def home(*args):
"""
Displays the directory where TIRL is installed.
"""
import tirl
print(tirl.home())
def config(*args):
"""
TIRL config utility. Allows the user to edit the settings.py file of
...
...
@@ -77,7 +87,6 @@ def info(*args):
Displays the ASCII header of a TIRL file using pretty formatting.
"""
# TODO: Make this feature compatible with TIRL v2.0
from tirl.tirlfile import info
if args:
info(args[0])
...
...
@@ -142,6 +151,7 @@ def _module_add(src, *args):
f"You need write permission in the directory {pkgdir} to "
f"change the active TIRL installation.")
# Copy the module source to the requested package directory
src = str(src) + ".py" if not str(src).lower().endswith(".py") else str(src)
shutil.copy2(src, os.path.join(pkgdir, os.path.basename(src)))
...
...
@@ -152,15 +162,23 @@ def _module_edit(src, *args):
module path with respect to the main TIRL package.
"""
import os
import tirl
import subprocess
if str(src).lower().endswith(".py"):
src = str(src)[:-3]
if "." not in src:
src = "usermodules." + src
module_file = tirl.home(*src.split(".")) + ".py"
if not os.path.isfile(module_file):
raise FileNotFoundError(f"Module file does not exist: {module_file}")
editor = "vim" if not args else args[0]
confirm = f"Do you wish to EDIT {module_file}? [y/n] ".lower()
while True:
ans = input(confirm)
if ans in ("y", "yes", "ye"):
subprocess.run([editor, module_file])
return
elif ans in ("n", "no"):
break
else:
...
...
@@ -175,6 +193,8 @@ def _module_remove(src):
"""
import os
import tirl
if str(src).endswith(".py"):
src = str(src)[:-3]
target = tirl.home("usermodules", *src.split("."))
if not os.path.isdir(target):
target += ".py"
...
...
@@ -186,6 +206,7 @@ def _module_remove(src):
if ans in ("y", "yes", "ye"):
try:
os.remove(target)
return
except:
raise PermissionError(
f"You need elevated permissions to remove {target}.")
...
...
tirl/tirlfile.py
View file @
fa6d0484
...
...
@@ -420,6 +420,30 @@ def load(fname):
return
object_dump
def
header
(
fname
):
""" Returns the header of a TIRLFile. """
with
open
(
fname
,
"rb"
)
as
fp
:
fp
.
seek
(
len
(
MAGIC
)
+
2
*
UINT8
.
nbytes
)
hdrsize
=
bytes2int
(
fp
.
read
(
UINT64
.
nbytes
),
UINT64
)
hdr
=
fp
.
read
(
hdrsize
)
return
json
.
loads
(
hdr
.
decode
())
def
info
(
fname
):
"""
Prints the formatted file header without parsing the binary part of the
file.
"""
from
pygments
import
highlight
,
lexers
,
formatters
hdr
=
header
(
fname
)
formatted_json
=
json
.
dumps
(
hdr
,
indent
=
4
)
colorful_json
=
highlight
(
formatted_json
.
encode
(
"UTF-8"
),
lexers
.
JsonLexer
(),
formatters
.
TerminalFormatter
())
print
(
colorful_json
)
def
encode
(
node
):
"""
Recursive function that traverses an object dump and replaces
...
...
tirl/tirlvision/sliceview.py
View file @
fa6d0484
#!/usr/bin/env python
#!/usr/bin/env fslpython
# -*- coding: utf-8 -*-
import
tirl
# _______ _____ _____ _
# |__ __| |_ _| | __ \ | |
# | | | | | |__) | | |
# | | | | | _ / | |
# | | _| |_ | | \ \ | |____
# |_| |_____| |_| \_\ |______|
#
# Copyright (C) 2018-2020 University of Oxford
# Part of the FMRIB Software Library (FSL)
# Author: Istvan N. Huszar
# Date: 23 June 2020
# SHBASECOPYRIGHT
__version__
=
"2020.6.0"
# DEPENDENCIES
import
sys
import
argparse
import
numpy
as
np
from
mayavi
import
mlab
from
scipy.spatial
import
Delaunay
# TIRL IMPORTS
import
tirl
# IMPLEMENTATION
def
sliceview
():
"""
Main program code.
"""
def
surfvis
():
images
=
[
...
...
@@ -43,6 +81,28 @@ def volslicer(fig):
mlab
.
show
()
def
create_cli
():
"""
Creates command-line interface.
"""
usage
=
"""./sliceview --slice """
parser
=
argparse
.
ArgumentParser
(
prog
=
"sliceview"
,
usage
=
usage
,
description
=
descr
)
def
main
(
*
args
):
""" Main program code. """
parser
=
create_cli
()
if
args
:
sliceview
(
parser
.
parse_args
(
args
))
else
:
parser
.
print_help
()
if
__name__
==
"__main__"
:
fig
=
surfvis
()
volslicer
(
fig
)
main
(
*
sys
.
argv
)
tirlenv.yml
View file @
fa6d0484
...
...
@@ -16,6 +16,7 @@ dependencies:
-
imagecodecs-lite
-
imageio
-
joblib
-
mayavi
-
matplotlib
-
nibabel
-
nlopt
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment