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
Sean Fitzgibbon
SlideR 馃崝
Commits
ff65be41
Commit
ff65be41
authored
Jul 13, 2021
by
Sean Fitzgibbon
Browse files
reformatting - no code changes
parent
eb4d5877
Changes
4
Expand all
Hide whitespace changes
Inline
Side-by-side
slider/chart_reg.py
View file @
ff65be41
#!/usr/bin/env python
#
#
# Copyright 2021 Sean Fitzgibbon, University of Oxford
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
import
os
import
os.path
as
op
import
json
...
...
@@ -31,19 +31,20 @@ from matplotlib import patches
import
numpy
as
np
import
matplotlib.pyplot
as
plt
def
register_chart_to_slide
(
chart
,
slide
,
slide_res
,
out
,
config
=
None
):
if
config
is
None
:
config
=
util
.
get_resource
(
'
chart.yaml
'
)
config
=
util
.
get_resource
(
"
chart.yaml
"
)
with
open
(
config
,
'r'
)
as
f
:
with
open
(
config
,
"r"
)
as
f
:
config
=
yaml
.
load
(
f
)
rlevel
=
config
[
'
slide
'
][
'
resolution_level
'
]
boundary_key
=
config
[
'
chart
'
][
'
boundary_key
'
]
rlevel
=
config
[
"
slide
"
][
"
resolution_level
"
]
boundary_key
=
config
[
"
chart
"
][
"
boundary_key
"
]
# set global variables required for summary plots
plots
=
config
[
'
general
'
][
'
plots
'
]
plots
=
config
[
"
general
"
][
"
plots
"
]
global
DO_PLOTS
DO_PLOTS
=
plots
...
...
@@ -54,11 +55,11 @@ def register_chart_to_slide(chart, slide, slide_res, out, config=None):
# create output dir
if
not
op
.
exists
(
out
):
os
.
makedirs
(
out
)
# load chart
contour
,
cells
=
neurolucida
.
read
(
chart
)
slide_res
=
slide_res
*
(
2
**
rlevel
)
slide_res
=
slide_res
*
(
2
**
rlevel
)
# load slide
jp2
=
glymur
.
Jp2k
(
slide
)
...
...
@@ -69,24 +70,28 @@ def register_chart_to_slide(chart, slide, slide_res, out, config=None):
init
=
_init_scale
(
img
,
slide_res
,
edge_crds
,
verbose
=
True
)
print
(
init
)
print
(
f
'Rotation:
{
init
.
rotation
}
, Translation:
{
init
.
translation
}
, Scale:
{
init
.
scale
}
, Shear:
{
init
.
shear
}
'
)
f
"Rotation:
{
init
.
rotation
}
, Translation:
{
init
.
translation
}
, Scale:
{
init
.
scale
}
, Shear:
{
init
.
shear
}
"
)
# calculate normal line to boundary points
xfm_edge_coords
=
_apply_xfm
(
init
,
edge_crds
)
init_nrmls
=
normal
(
xfm_edge_coords
)
# refine edge_coords (to image)
refined_edge_coords
=
_refine_edge_coord
(
img
,
slide_res
,
xfm_edge_coords
,
init_nrmls
)
refined_edge_coords
=
_refine_edge_coord
(
img
,
slide_res
,
xfm_edge_coords
,
init_nrmls
)
# estimate opimised affine transform
opt
=
transform
.
AffineTransform
()
opt
.
estimate
(
edge_crds
,
refined_edge_coords
)
print
(
opt
)
print
(
f
'Rotation:
\t
{
opt
.
rotation
}
\n
Translation:
\t
{
opt
.
translation
}
\n
Scale:
\t\t
{
list
(
opt
.
scale
)
}
\n
Shear:
\t\t
{
opt
.
shear
}
'
)
f
"Rotation:
\t
{
opt
.
rotation
}
\n
Translation:
\t
{
opt
.
translation
}
\n
Scale:
\t\t
{
list
(
opt
.
scale
)
}
\n
Shear:
\t\t
{
opt
.
shear
}
"
)
# save opt transform
np
.
savetxt
(
f
'
{
out
}
/chart-to-image.xfm
'
,
opt
.
params
)
np
.
savetxt
(
f
"
{
out
}
/chart-to-image.xfm
"
,
opt
.
params
)
# apply opt-xfm to contours and cells and save
...
...
@@ -104,17 +109,17 @@ def register_chart_to_slide(chart, slide, slide_res, out, config=None):
coords
=
np
.
array
(
coords
)
cog
=
np
.
mean
(
coords
,
axis
=
0
)
ax
.
text
(
cog
[
0
],
cog
[
1
],
name
)
ax
.
plot
(
coords
[:,
0
],
coords
[:,
1
],
'k-'
)
cog
=
np
.
mean
(
coords
,
axis
=
0
)
ax
.
text
(
cog
[
0
],
cog
[
1
],
name
)
ax
.
plot
(
coords
[:,
0
],
coords
[:,
1
],
"k-"
)
ax
.
set_xlabel
(
"mm"
)
ax
.
set_ylabel
(
"mm"
)
ax
.
set_title
(
"Aligned Chart"
)
ax
.
set_xlabel
(
'mm'
)
ax
.
set_ylabel
(
'mm'
)
ax
.
set_title
(
'Aligned Chart'
)
fig
.
savefig
(
f
'
{
OUTDIR
}
/aligned_chart.png'
,
bbox_inches
=
'tight'
,
dpi
=
300
)
fig
.
savefig
(
f
"
{
OUTDIR
}
/aligned_chart.png"
,
bbox_inches
=
"tight"
,
dpi
=
300
)
# fig, ax = plt.subplots(1, 5, figsize=(25, 5))
# fig, ax = plt.subplots(1, 5, figsize=(25, 5))
# ax[0].imshow(plt.imread(f'{OUTDIR}/chart_bounding_box.png'))
# ax[1].imshow(plt.imread(f'{OUTDIR}/image_bounding_box.png'))
# ax[2].imshow(plt.imread(f'{OUTDIR}/normals.png'))
...
...
@@ -126,14 +131,12 @@ def register_chart_to_slide(chart, slide, slide_res, out, config=None):
# fig.savefig(f'{OUTDIR}/alignment.png', bbox_inches='tight', dpi=150)
with
open
(
f
'
{
out
}
/contour.json'
,
'w'
)
as
fp
:
with
open
(
f
"
{
out
}
/contour.json"
,
"w"
)
as
fp
:
json
.
dump
(
contour_xfm
,
fp
,
indent
=
4
)
if
cells
.
size
>
0
:
cells_xfm
=
_apply_xfm
(
cells
[:,
:
2
]
*
[
1
,
-
1
])
with
open
(
f
'
{
out
}
/cells.json
'
,
'w'
)
as
fp
:
with
open
(
f
"
{
out
}
/cells.json
"
,
"w"
)
as
fp
:
json
.
dump
(
cells_xfm
,
fp
,
indent
=
4
)
...
...
@@ -151,12 +154,12 @@ def _refine_edge_coord(img, img_res, edge_coords, normals):
line_x
=
edge_x
[:,
np
.
newaxis
]
+
nrml_x
[:,
np
.
newaxis
]
*
line_smpl
line_y
=
edge_y
[:,
np
.
newaxis
]
+
nrml_y
[:,
np
.
newaxis
]
*
line_smpl
# find threshold for background
image
=
rgb2gray
(
img
)
threshold_value
=
filters
.
threshold_otsu
(
image
)
print
(
f
'
threshold=
{
threshold_value
}
'
)
print
(
f
"
threshold=
{
threshold_value
}
"
)
# binarise foreground
# NOTE: this assumes a bright background!
...
...
@@ -170,7 +173,7 @@ def _refine_edge_coord(img, img_res, edge_coords, normals):
ridx
=
np
.
argmax
([
p0
.
area
for
p0
in
p
])
p
=
p
[
ridx
]
cc0
=
(
cc
==
p
.
label
)
cc0
=
cc
==
p
.
label
if
DO_PLOTS
:
fig
,
ax
=
plt
.
subplots
(
figsize
=
(
20
,
30
))
...
...
@@ -179,16 +182,15 @@ def _refine_edge_coord(img, img_res, edge_coords, normals):
ax
.
imshow
(
cc0
,
extent
=
extent
)
for
line_x0
,
line_y0
in
zip
(
line_x
,
line_y
):
ax
.
plot
(
line_x0
,
line_y0
,
'
b.
'
)
ax
.
plot
(
line_x0
,
line_y0
,
"
b.
"
)
ax
.
plot
(
edge_x
,
edge_y
,
'
r.
'
)
ax
.
plot
(
edge_x
,
edge_y
,
"
r.
"
)
ax
.
set_xlabel
(
'mm'
)
ax
.
set_ylabel
(
'mm'
)
ax
.
set_title
(
'Largest connected component + normals'
)
fig
.
savefig
(
f
'
{
OUTDIR
}
/normals.png'
,
bbox_inches
=
'tight'
,
dpi
=
300
)
ax
.
set_xlabel
(
"mm"
)
ax
.
set_ylabel
(
"mm"
)
ax
.
set_title
(
"Largest connected component + normals"
)
fig
.
savefig
(
f
"
{
OUTDIR
}
/normals.png"
,
bbox_inches
=
"tight"
,
dpi
=
300
)
# sample image along normal line
...
...
@@ -199,10 +201,13 @@ def _refine_edge_coord(img, img_res, edge_coords, normals):
min_idx
=
np
.
argmax
(
np
.
diff
(
line_int
,
axis
=-
1
),
axis
=-
1
)
refined_edge_coords
=
np
.
stack
([
line_x
[
np
.
arange
(
min_idx
.
size
),
min_idx
]
*
img_res
,
line_y
[
np
.
arange
(
min_idx
.
size
),
min_idx
]
*
img_res
,
],
axis
=-
1
)
refined_edge_coords
=
np
.
stack
(
[
line_x
[
np
.
arange
(
min_idx
.
size
),
min_idx
]
*
img_res
,
line_y
[
np
.
arange
(
min_idx
.
size
),
min_idx
]
*
img_res
,
],
axis
=-
1
,
)
# TODO: plot edge_coords + refined_edge_coords
if
DO_PLOTS
:
...
...
@@ -211,17 +216,16 @@ def _refine_edge_coord(img, img_res, edge_coords, normals):
extent
=
np
.
array
([
0
,
img
.
shape
[
1
],
img
.
shape
[
0
],
0
])
*
img_res
ax
.
imshow
(
img
,
extent
=
extent
)
ax
.
plot
(
edge_x
,
edge_y
,
'
r.-
'
)
ax
.
plot
(
refined_edge_coords
[:,
0
],
refined_edge_coords
[:,
1
],
'
g.-
'
)
ax
.
plot
(
edge_x
,
edge_y
,
"
r.-
"
)
ax
.
plot
(
refined_edge_coords
[:,
0
],
refined_edge_coords
[:,
1
],
"
g.-
"
)
ax
.
set_xlabel
(
'
mm
'
)
ax
.
set_ylabel
(
'
mm
'
)
ax
.
set_xlabel
(
"
mm
"
)
ax
.
set_ylabel
(
"
mm
"
)
# ax.set_title('edge_co')
ax
.
legend
([
'edge_coords'
,
'refined_edge_coords'
])
fig
.
savefig
(
f
'
{
OUTDIR
}
/refined_coords.png'
,
bbox_inches
=
'tight'
,
dpi
=
150
)
ax
.
legend
([
"edge_coords"
,
"refined_edge_coords"
])
fig
.
savefig
(
f
"
{
OUTDIR
}
/refined_coords.png"
,
bbox_inches
=
"tight"
,
dpi
=
150
)
return
refined_edge_coords
...
...
@@ -235,7 +239,7 @@ def _img_props(img, img_resolution, verbose=False):
threshold_value
=
filters
.
threshold_otsu
(
image
)
if
verbose
:
print
(
f
'
threshold=
{
threshold_value
}
'
)
print
(
f
"
threshold=
{
threshold_value
}
"
)
# binarise foreground
# NOTE: this assumes a bright background!
...
...
@@ -253,8 +257,8 @@ def _img_props(img, img_resolution, verbose=False):
bbox
=
np
.
array
(
p
.
bbox
)
*
img_resolution
centroid
=
(
(
bbox
[
0
]
+
bbox
[
2
])
/
2
,
(
bbox
[
1
]
+
bbox
[
3
])
/
2
,
(
bbox
[
0
]
+
bbox
[
2
])
/
2
,
(
bbox
[
1
]
+
bbox
[
3
])
/
2
,
)
if
DO_PLOTS
:
...
...
@@ -267,27 +271,27 @@ def _img_props(img, img_resolution, verbose=False):
rect
=
patches
.
Rectangle
(
(
bbox
[
1
],
bbox
[
0
]),
bbox
[
3
]
-
bbox
[
1
],
bbox
[
2
]
-
bbox
[
0
],
bbox
[
3
]
-
bbox
[
1
],
bbox
[
2
]
-
bbox
[
0
],
linewidth
=
1
,
edgecolor
=
'r'
,
facecolor
=
'
none
'
edgecolor
=
"r"
,
facecolor
=
"
none
"
,
)
ax
.
add_patch
(
rect
)
ax
.
plot
(
centroid
[
1
],
centroid
[
0
],
'
ro
'
)
ax
.
set_xlabel
(
'
mm
'
)
ax
.
set_ylabel
(
'
mm
'
)
ax
.
set_title
(
'
Image bounding box
'
)
fig
.
savefig
(
f
'
{
OUTDIR
}
/image_bounding_box.png
'
,
bbox_inches
=
'
tight
'
,
dpi
=
150
)
ax
.
plot
(
centroid
[
1
],
centroid
[
0
],
"
ro
"
)
ax
.
set_xlabel
(
"
mm
"
)
ax
.
set_ylabel
(
"
mm
"
)
ax
.
set_title
(
"
Image bounding box
"
)
fig
.
savefig
(
f
"
{
OUTDIR
}
/image_bounding_box.png
"
,
bbox_inches
=
"
tight
"
,
dpi
=
150
)
return
{
'
bbox
'
:
bbox
,
'
bbox_centroid
'
:
centroid
,
'
shape
'
:
(
bbox
[
2
]
-
bbox
[
0
],
bbox
[
3
]
-
bbox
[
1
])
}
"
bbox
"
:
bbox
,
"
bbox_centroid
"
:
centroid
,
"
shape
"
:
(
bbox
[
2
]
-
bbox
[
0
],
bbox
[
3
]
-
bbox
[
1
])
,
}
def
_pnt_props
(
pnts
,
verbose
=
False
):
...
...
@@ -295,47 +299,46 @@ def _pnt_props(pnts, verbose=False):
x
=
pnts
[:,
0
]
y
=
pnts
[:,
1
]
bbox
=
(
np
.
min
(
y
),
np
.
min
(
x
),
np
.
max
(
y
),
np
.
max
(
x
)
)
bbox
=
(
np
.
min
(
y
),
np
.
min
(
x
),
np
.
max
(
y
),
np
.
max
(
x
))
centroid
=
(
(
bbox
[
0
]
+
bbox
[
2
])
/
2
,
(
bbox
[
1
]
+
bbox
[
3
])
/
2
,
(
bbox
[
0
]
+
bbox
[
2
])
/
2
,
(
bbox
[
1
]
+
bbox
[
3
])
/
2
,
)
if
verbose
:
print
(
f
'
bbox=
{
bbox
}
'
)
print
(
f
'
centroid=
{
centroid
}
'
)
print
(
f
"
bbox=
{
bbox
}
"
)
print
(
f
"
centroid=
{
centroid
}
"
)
if
DO_PLOTS
:
fig
,
ax
=
plt
.
subplots
()
ax
.
plot
(
x
,
y
,
'
b.
'
)
ax
.
axis
(
'
equal
'
)
ax
.
plot
(
x
,
y
,
"
b.
"
)
ax
.
axis
(
"
equal
"
)
ax
.
invert_yaxis
()
rect
=
patches
.
Rectangle
(
(
bbox
[
1
],
bbox
[
0
]),
bbox
[
3
]
-
bbox
[
1
],
bbox
[
2
]
-
bbox
[
0
],
bbox
[
3
]
-
bbox
[
1
],
bbox
[
2
]
-
bbox
[
0
],
linewidth
=
1
,
edgecolor
=
'r'
,
facecolor
=
'
none
'
edgecolor
=
"r"
,
facecolor
=
"
none
"
,
)
ax
.
add_patch
(
rect
)
plt
.
plot
(
centroid
[
1
],
centroid
[
0
],
'ro'
)
plt
.
plot
(
centroid
[
1
],
centroid
[
0
],
"ro"
)
ax
.
set_title
(
"Chart bounding box"
)
ax
.
set_title
(
'Chart bounding box'
)
fig
.
savefig
(
f
'
{
OUTDIR
}
/chart_bounding_box.png'
,
bbox_inches
=
'tight'
,
dpi
=
150
)
fig
.
savefig
(
f
"
{
OUTDIR
}
/chart_bounding_box.png"
,
bbox_inches
=
"tight"
,
dpi
=
150
)
return
{
'bbox'
:
bbox
,
'bbox_centroid'
:
centroid
,
'shape'
:
(
bbox
[
2
]
-
bbox
[
0
],
bbox
[
3
]
-
bbox
[
1
])}
return
{
"bbox"
:
bbox
,
"bbox_centroid"
:
centroid
,
"shape"
:
(
bbox
[
2
]
-
bbox
[
0
],
bbox
[
3
]
-
bbox
[
1
]),
}
def
_init_scale
(
img
,
img_resolution
,
crd
,
verbose
=
False
):
...
...
@@ -344,13 +347,13 @@ def _init_scale(img, img_resolution, crd, verbose=False):
crd_p
=
_pnt_props
(
crd
)
if
verbose
:
print
(
f
'
image props =
{
img_p
}
'
)
print
(
f
'
chart props =
{
crd_p
}
'
)
print
(
f
"
image props =
{
img_p
}
"
)
print
(
f
"
chart props =
{
crd_p
}
"
)
idx
=
np
.
array
([[
1
,
2
],
[
1
,
0
],
[
3
,
2
],
[
3
,
0
]])
src
=
np
.
array
(
crd_p
[
'
bbox
'
])[
idx
]
dest
=
np
.
array
(
img_p
[
'
bbox
'
])[
idx
]
src
=
np
.
array
(
crd_p
[
"
bbox
"
])[
idx
]
dest
=
np
.
array
(
img_p
[
"
bbox
"
])[
idx
]
a
=
transform
.
AffineTransform
()
a
.
estimate
(
src
,
dest
)
...
...
@@ -359,7 +362,9 @@ def _init_scale(img, img_resolution, crd, verbose=False):
def
_apply_xfm
(
xfm
,
pnts
):
return
(
xfm
.
params
@
np
.
concatenate
((
pnts
,
np
.
ones
((
pnts
.
shape
[
0
],
1
))),
axis
=-
1
).
T
).
T
[:,
:
2
]
return
(
xfm
.
params
@
np
.
concatenate
((
pnts
,
np
.
ones
((
pnts
.
shape
[
0
],
1
))),
axis
=-
1
).
T
).
T
[:,
:
2
]
def
normal
(
pnts
):
...
...
slider/report.py
View file @
ff65be41
#!/usr/bin/env python
#
#
# Copyright 2021 Sean Fitzgibbon, University of Oxford
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
import
jinja2
import
os.path
as
op
import
os
import
base64
def
report_reg
(
dirs
,
out
,
embed
=
False
):
images
=
[
f
'
{
d
}
/alignment.png
'
for
d
in
dirs
]
images
=
[
f
"
{
d
}
/alignment.png
"
for
d
in
dirs
]
images
=
[
d
for
d
in
images
if
op
.
exists
(
d
)]
images
=
[(
op
.
dirname
(
f
),
to_base64
(
f
)
if
embed
else
f
)
for
f
in
images
]
env
=
jinja2
.
Environment
(
loader
=
jinja2
.
PackageLoader
(
'
slider
'
,
'
resources
'
),
autoescape
=
jinja2
.
select_autoescape
([
'
html
'
,
'
xml
'
]),
extensions
=
[
'
jinja2.ext.do
'
]
loader
=
jinja2
.
PackageLoader
(
"
slider
"
,
"
resources
"
),
autoescape
=
jinja2
.
select_autoescape
([
"
html
"
,
"
xml
"
]),
extensions
=
[
"
jinja2.ext.do
"
],
)
template
=
env
.
get_template
(
'
registration_report_template.html
'
)
template
=
env
.
get_template
(
"
registration_report_template.html
"
)
html
=
template
.
render
(
images
=
images
,
)
with
open
(
out
,
'w'
)
as
outfile
:
with
open
(
out
,
"w"
)
as
outfile
:
outfile
.
write
(
html
)
def
to_base64
(
fname
):
with
open
(
fname
,
'
rb
'
)
as
tmp
:
with
open
(
fname
,
"
rb
"
)
as
tmp
:
tmp
.
seek
(
0
)
s
=
base64
.
b64encode
(
tmp
.
read
()).
decode
(
"utf-8"
)
return
'
data:image/{};base64,
'
.
format
(
op
.
splitext
(
fname
)[
-
1
])
+
s
return
"
data:image/{};base64,
"
.
format
(
op
.
splitext
(
fname
)[
-
1
])
+
s
slider/slide_reg.py
View file @
ff65be41
This diff is collapsed.
Click to expand it.
slider_app.py
View file @
ff65be41
#!/usr/bin/env python
#
#
# Copyright 2021 Sean Fitzgibbon, University of Oxford
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
import
argparse
import
sys
...
...
@@ -22,33 +22,54 @@ from slider.chart_reg import register_chart_to_slide
from
slider.batch
import
run_batch
from
slider.report
import
report_reg
def
add_slide_cli
(
subparsers
):
"""
Set up slide-to-slide subparser instance.
"""
parser
=
subparsers
.
add_parser
(
'SLIDE'
,
description
=
'Register 2D slide to 2D slide'
,
formatter_class
=
lambda
prog
:
argparse
.
HelpFormatter
(
prog
,
max_help_position
=
55
,
width
=
100
)
"SLIDE"
,
description
=
"Register 2D slide to 2D slide"
,
formatter_class
=
lambda
prog
:
argparse
.
HelpFormatter
(
prog
,
max_help_position
=
55
,
width
=
100
),
)
parser
.
add_argument
(
"moving"
,
metavar
=
"<moving>"
,
help
=
"Moving slide image"
,
type
=
str
)
parser
.
add_argument
(
"moving_res"
,
metavar
=
"<moving-resolution>"
,
help
=
"Moving image resolution (mm)"
,
type
=
float
)
parser
.
add_argument
(
"moving"
,
metavar
=
"<moving>"
,
help
=
"Moving slide image"
,
type
=
str
)
parser
.
add_argument
(
"moving_res"
,
metavar
=
"<moving-resolution>"
,
help
=
"Moving image resolution (mm)"
,
type
=
float
,
)
parser
.
add_argument
(
"fixed"
,
metavar
=
"<fixed>"
,
help
=
"Fixed slide image"
,
type
=
str
)
parser
.
add_argument
(
"fixed_res"
,
metavar
=
"<fixed-resolution>"
,
help
=
"Fixed image resolution (mm)"
,
type
=
float
)
parser
.
add_argument
(
"fixed"
,
metavar
=
"<fixed>"
,
help
=
"Fixed slide image"
,
type
=
str
)
parser
.
add_argument
(
"fixed_res"
,
metavar
=
"<fixed-resolution>"
,
help
=
"Fixed image resolution (mm)"
,
type
=
float
,
)
parser
.
add_argument
(
"--out"
,
metavar
=
"<dir>"
,
help
=
"Output directory"
,
default
=
'./slide-to-slide.reg'
,
type
=
str
,
required
=
False
)
parser
.
add_argument
(
"--config"
,
metavar
=
"<config.json>"
,
help
=
"configuration file"
,
default
=
None
,
type
=
str
,
required
=
False
)
parser
.
set_defaults
(
method
=
'slide'
)
parser
.
add_argument
(
"--out"
,
metavar
=
"<dir>"
,
help
=
"Output directory"
,
default
=
"./slide-to-slide.reg"
,
type
=
str
,
required
=
False
,
)
parser
.
add_argument
(
"--config"
,
metavar
=
"<config.json>"
,
help
=
"configuration file"
,
default
=
None
,
type
=
str
,
required
=
False
,
)
parser
.
set_defaults
(
method
=
"slide"
)
def
add_chart_cli
(
subparsers
):
...
...
@@ -56,23 +77,39 @@ def add_chart_cli(subparsers):
Set up chart-to-slide subparser instance.
"""
parser
=
subparsers
.
add_parser
(
'CHART'
,
description
=
'Register charting to 2D slide'
,
formatter_class
=
lambda
prog
:
argparse
.
HelpFormatter
(
prog
,
max_help_position
=
55
,
width
=
100
)
)
parser
.
add_argument
(
"chart"
,
metavar
=
"<chart>"
,
help
=
"Neurolucida chart file"
,
type
=
str
)
parser
.
add_argument
(
"slide"
,
metavar
=
"<slide>"
,
help
=
"Fixed slide"
,
type
=
str
)
parser
.
add_argument
(
"slide_res"
,
metavar
=
"<slide-resolution>"
,
help
=
"Slide image resolution (mm)"
,
type
=
float
)
parser
.
add_argument
(
"--out"
,
metavar
=
"<dir>"
,
help
=
"Output directory"
,
default
=
'./chart-to-slide.reg'
,
type
=
str
,
required
=
False
)
parser
.
add_argument
(
"--config"
,
metavar
=
"<config.yaml>"
,
help
=
"configuration file"
,
default
=
None
,
type
=
str
,
required
=
False
)
parser
.
set_defaults
(
method
=
'chart'
)
"CHART"
,
description
=
"Register charting to 2D slide"
,
formatter_class
=
lambda
prog
:
argparse
.
HelpFormatter
(
prog
,
max_help_position
=
55
,
width
=
100
),
)
parser
.
add_argument
(
"chart"
,
metavar
=
"<chart>"
,
help
=
"Neurolucida chart file"
,
type
=
str
)
parser
.
add_argument
(
"slide"
,
metavar
=
"<slide>"
,
help
=
"Fixed slide"
,
type
=
str
)
parser
.
add_argument
(
"slide_res"
,
metavar
=
"<slide-resolution>"
,
help
=
"Slide image resolution (mm)"
,
type
=
float
,
)
parser
.
add_argument
(
"--out"
,
metavar
=
"<dir>"
,
help
=
"Output directory"
,
default
=
"./chart-to-slide.reg"
,
type
=
str
,
required
=
False
,
)
parser
.
add_argument
(
"--config"
,
metavar
=
"<config.yaml>"
,
help
=
"configuration file"
,
default
=
None
,
type
=
str
,
required
=
False
,
)
parser
.
set_defaults
(
method
=
"chart"
)
def
add_applyxfm_cli
(
subparsers
):
...
...
@@ -80,36 +117,67 @@ def add_applyxfm_cli(subparsers):
Set up applyxfm subparser instance.
"""
parser
=
subparsers
.
add_parser
(
'APPLYXFM'
,
description
=
'Apply transform to image.'
,
formatter_class
=
lambda
prog
:
argparse
.
HelpFormatter
(
prog
,
max_help_position
=
55
,
width
=
100
)
"APPLYXFM"
,
description
=
"Apply transform to image."
,