Commit f7da6821 authored by Sean Fitzgibbon's avatar Sean Fitzgibbon
Browse files

Added improved masking and some temporary debugging code

parent 944d74f5
......@@ -31,7 +31,7 @@ moving:
uthr: 1
file: null
# function: null
function: gmm_mask
function: threshold_mask
normalise: true
preview: false
resolution_level: 4
......@@ -48,7 +48,7 @@ fixed:
thr: 0
uthr: 1
file: null
function: gmm_mask
function: threshold_mask
# function: null
normalise: true
preview: false
......
......@@ -100,6 +100,7 @@ __tirlscript__ = True
import argparse
import json, yaml
import skimage
from numpy.lib.shape_base import _kron_dispatcher
import logging
import os
......@@ -118,6 +119,7 @@ from tirl.beta import beta_function
from tirl.chain import Chain
from tirl.constants import *
from tirl.costs.mind import CostMIND
# from tirl.costs.mi import CostMI
from tirl.optimisation.gnoptdiff import GNOptimiserDiffusion
from tirl.optimisation.optgroup import OptimisationGroup
from tirl.optimisation.optnl import OptNL
......@@ -224,12 +226,22 @@ def run(cnf=None, **options):
moving = _load_image(p.moving)
moving.snapshot(
os.path.join(p.general.outputdir, f"moving0_input.{SNAPSHOT_EXT}"),
overwrite=True,
)
if p.fixed.export is True:
ext = ts.EXTENSIONS["TImage"]
p.fixed.export = os.path.join(p.general.outputdir, f"fixed.{ext}")
fixed = _load_image(p.fixed)
fixed.snapshot(
os.path.join(p.general.outputdir, f"fixed0_input.{SNAPSHOT_EXT}"),
overwrite=True,
)
# Having loaded both images, perform actions on the histology image prior
# to registration, unless it was loaded from a TImage.
# Actions are user-defined functions within the TIRL namespace. Actions
......@@ -799,11 +811,40 @@ def diffreg2d(fixed, moving, cnf):
maskmode=q.maskmode,
)
# cost = CostMI(
# moving_smooth,
# fixed_smooth,
# # sigma=float(q.sigma),
# # truncate=float(q.truncate),
# kernel=kernel,
# maskmode=q.maskmode,
# )
# np.save(
# os.path.join(p.general.outputdir, f"cost_sc{sc}.npy"),
# cost.costmap().data,
# )
# from skimage import io
# for idx in range(cost.costmap().data.shape[0]):
# io.imsave(
# os.path.join(p.general.outputdir, f"cost_sc{sc}_{idx}.png"),
# np.squeeze(cost.costmap().data[idx,...])
# )
# import nibabel as nb
# print(cost.costmap().data.shape)
# if cost.costmap().data.ndim == 2:
# cd0 = cost.costmap().data[..., np.newaxis].transpose([2, 1, 0])
# else:
# cd0 = cost.costmap().data.transpose([3, 2, 1, 0])
# cd0 = np.flip(cd0, axis=1)
# nb.Nifti1Image(cd0.astype(float), affine=np.eye(4)).to_filename(os.path.join(p.general.outputdir, f"cost_sc{sc}.nii.gz"))
regularisation = DiffusionRegulariser(tx_nonlinear, weight=float(q.regweight))
# Optimise the non-linear transformation
GNOptimiserDiffusion(
......@@ -842,6 +883,31 @@ def diffreg2d(fixed, moving, cnf):
# included here to prevent too frequent code repetitions.
def threshold_mask(img):
from skimage import color, exposure, filters, measure, morphology
d0 = color.rgb2hsv(img.data.astype(np.uint8))[..., -1]
d0 = exposure.equalize_hist(d0)
thr = filters.threshold_li(d0)
d0 = d0 < thr
cc = measure.label(d0, background=0)
p = measure.regionprops(cc, d0)
ridx = np.argmax([p0.area for p0 in p])
p = p[ridx]
d0 = cc==p.label
d0 = morphology.area_closing(d0)
d0 = morphology.binary_dilation(d0, morphology.disk(60, dtype=bool))
d0 = morphology.binary_erosion(d0, morphology.disk(50, dtype=bool))
return d0.astype(int)
def gmm_mask(img, gmm_comps=3, dilation_radius=2):
from skimage.measure import regionprops, label
......@@ -958,11 +1024,11 @@ def match_fixed_resolution(img, **kwargs):
logger.info(f"Shape of the 2D image after resampling: {img.shape}.")
# Save low-resolution image
fp, fn = os.path.split(p.moving.file)
fn, ext = os.path.splitext(fn)
filename = os.path.join(p.general.outputdir, f"{fn}_lowres.{SNAPSHOT_EXT}")
img.snapshot(filename, overwrite=True)
logger.info(f"Saved low-resolution snapshot of the 2D image to: {filename}")
# fp, fn = os.path.split(p.moving.file)
# fn, ext = os.path.splitext(fn)
# filename = os.path.join(p.general.outputdir, f"{fn}_lowres.{SNAPSHOT_EXT}")
# img.snapshot(filename, overwrite=True)
# logger.info(f"Saved low-resolution snapshot of the 2D image to: {filename}")
return img
......@@ -1000,6 +1066,23 @@ def moving_preprocessing(histo, **kwargs):
# Convert to grayscale using the Y channel of the YIQ colour space.
return tirl.scripts.mnd.image.rgb2yiq(histo.tensors[:3]).tensors[0]
# from skimage import exposure
# from skimage import color
# p = AttrMap(kwargs.get("cnf"))
# logger = logging.getLogger(p.logger)
# logger.info('Pre-process moving image')
# pp = exposure.equalize_adapthist(np.prod(color.rgb2hsv(histo.data)[...,1:], axis=-1))
# pp = TImage.fromarray(pp[..., np.newaxis], tensor_axes=(2,), dtype='f4')
# pp.resolution = histo.resolution
# pp.mask = histo.mask
# return pp
def preprocessing_resample(img, **kwargs):
p = AttrMap(kwargs.get("cnf"))
......@@ -1028,6 +1111,22 @@ def fixed_preprocessing(block, **kwargs):
# Convert to grayscale using the Y channel of the YIQ colour space.
return tirl.scripts.mnd.image.rgb2yiq(block.tensors[:3]).tensors[0]
# from skimage import exposure
# from skimage import color
# p = AttrMap(kwargs.get("cnf"))
# logger = logging.getLogger(p.logger)
# logger.info('Pre-process fixed image')
# pp = exposure.equalize_adapthist(np.prod(color.rgb2hsv(block.data)[...,1:], axis=-1))
# pp = TImage.fromarray(pp[..., np.newaxis], tensor_axes=(2,), dtype='f4')
# pp.resolution = block.resolution
# pp.mask = block.mask
# return pp
def hsv_sat(timg, **kwargs):
from skimage.color import rgb2hsv
......@@ -1145,13 +1244,13 @@ def register_slide_to_slide(moving, moving_res, fixed, fixed_res, out, config=No
if config is None:
config = util.get_resource("slide.yaml")
if os.path.isfile(config):
if isinstance(config, str) and os.path.isfile(config):
with open(config, "r") as fp:
config = yaml.load(fp)
else:
raise FileNotFoundError(
f"The provided configuration file " f"does not exist: {config}"
)
# else:
# raise FileNotFoundError(
# f"The provided configuration file " f"does not exist: {config}"
# )
config["moving"]["file"] = moving
config["moving"]["resolution"] = moving_res
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment