inital commit
This commit is contained in:
commit
822692d032
7 changed files with 685 additions and 0 deletions
127
1-move.py
Executable file
127
1-move.py
Executable file
|
@ -0,0 +1,127 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
from pydicom.dataset import Dataset
|
||||
|
||||
from pynetdicom import AE, evt, StoragePresentationContexts, debug_logger
|
||||
from pynetdicom.sop_class import PatientRootQueryRetrieveInformationModelMove
|
||||
|
||||
# debug_logger()
|
||||
|
||||
Series = {}
|
||||
|
||||
dcm_dir = '/nn'
|
||||
|
||||
def handle_store(event):
|
||||
# print(event)
|
||||
"""Handle a C-STORE request event."""
|
||||
ds = event.dataset
|
||||
ds.file_meta = event.file_meta
|
||||
|
||||
# print(ds.SeriesInstanceUID)
|
||||
|
||||
if ds.SeriesInstanceUID in Series:
|
||||
s = Series[ds.SeriesInstanceUID]
|
||||
else:
|
||||
number = len(Series)
|
||||
series_dir = os.path.join(dcm_dir, ds.PatientID, ds.StudyInstanceUID, ds.SeriesInstanceUID, str(number))
|
||||
series_dir = os.path.join(dcm_dir, ds.PatientID, ds.StudyDate, ds.Modality, str(number))
|
||||
series_dir = os.path.join(dcm_dir, ds.PatientID, ds.StudyDate, ds.Modality, hex(number)[2:])
|
||||
s = {
|
||||
'PatientID': ds.PatientID,
|
||||
'StudyInstanceUID': ds.StudyInstanceUID,
|
||||
'SeriesInstanceUID': ds.SeriesInstanceUID,
|
||||
|
||||
'Modality': ds.Modality,
|
||||
'SeriesDescription': ds.SeriesDescription,
|
||||
|
||||
'path': series_dir,
|
||||
'number': number,
|
||||
}
|
||||
# print(s)
|
||||
print(s['path'], s['SeriesDescription'])
|
||||
Series[ds.SeriesInstanceUID] = s
|
||||
|
||||
os.makedirs(s['path'], exist_ok=True)
|
||||
|
||||
filename = os.path.join(s['path'], ds.SOPInstanceUID)
|
||||
|
||||
# Save the dataset using the SOP Instance UID as the filename
|
||||
ds.save_as(filename, write_like_original=False)
|
||||
|
||||
# Return a 'Success' status
|
||||
return 0x0000
|
||||
|
||||
def QueryDCM(PatientID):
|
||||
|
||||
handlers = [(evt.EVT_C_STORE, handle_store)]
|
||||
|
||||
# Initialise the Application Entity
|
||||
ae = AE()
|
||||
|
||||
# Add a requested presentation context
|
||||
ae.add_requested_context(PatientRootQueryRetrieveInformationModelMove)
|
||||
|
||||
# Add the Storage SCP's supported presentation contexts
|
||||
ae.supported_contexts = StoragePresentationContexts
|
||||
|
||||
# Start our Storage SCP in non-blocking mode, listening on port 11120
|
||||
ae.ae_title = 'OUR_STORE_SCP'
|
||||
# scp = ae.start_server(("127.0.0.1", 11120), block=False, evt_handlers=handlers)
|
||||
scp = ae.start_server(("0.0.0.0", 11120), block=False, evt_handlers=handlers)
|
||||
|
||||
# Create out identifier (query) dataset
|
||||
ds = Dataset()
|
||||
ds.QueryRetrieveLevel = 'PATIENT'
|
||||
ds.PatientID = PatientID
|
||||
|
||||
|
||||
# Associate with peer AE at IP 127.0.0.1 and port 11112
|
||||
# assoc = ae.associate("127.0.0.1", 11112)
|
||||
assoc = ae.associate("192.168.10.56", 104,
|
||||
ae_title = 'IQWEBX',
|
||||
)
|
||||
|
||||
|
||||
if assoc.is_established:
|
||||
# Use the C-MOVE service to send the identifier
|
||||
responses = assoc.send_c_move(ds, 'OUR_STORE_SCP', PatientRootQueryRetrieveInformationModelMove)
|
||||
|
||||
for (status, identifier) in responses:
|
||||
# print(status, identifier)
|
||||
if status:
|
||||
print('C-MOVE query status: 0x{0:04x}'.format(status.Status))
|
||||
else:
|
||||
print('Connection timed out, was aborted or received invalid response')
|
||||
|
||||
# Release the association
|
||||
assoc.release()
|
||||
else:
|
||||
print('Association rejected, aborted or never connected')
|
||||
|
||||
# Stop our Storage SCP
|
||||
scp.shutdown()
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print('Usage:', sys.argv[0], 'PatientID')
|
||||
sys.exit()
|
||||
print('hello')
|
||||
print(sys.argv[0])
|
||||
print(sys.argv[1])
|
||||
|
||||
start = time.time()
|
||||
QueryDCM(sys.argv[1])
|
||||
end = time.time()
|
||||
print(end - start, 'seconds')
|
||||
|
||||
# for k, v in Series.items():
|
||||
# print(v['number'], v['Modality'], v['SeriesDescription'], v['path'])
|
||||
# print(v['path'], v['SeriesDescription'])
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
147
2-infer.py
Executable file
147
2-infer.py
Executable file
|
@ -0,0 +1,147 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import difflib
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
from nipype.interfaces.dcm2nii import Dcm2niix
|
||||
from rt_utils import RTStructBuilder
|
||||
|
||||
import numpy as np
|
||||
import SimpleITK as sitk
|
||||
|
||||
|
||||
import itk_elastix
|
||||
|
||||
|
||||
def dcm2nii(source_dir, output_dir):
|
||||
|
||||
# print(source_dir)
|
||||
# print(output_dir)
|
||||
|
||||
converter = Dcm2niix()
|
||||
converter.inputs.source_dir = source_dir
|
||||
# converter.inputs.compression = 5
|
||||
converter.inputs.output_dir = output_dir
|
||||
print(converter.cmdline)
|
||||
converter.run()
|
||||
|
||||
|
||||
def register(DCM_CT, DCM_MR):
|
||||
|
||||
matcher = difflib.SequenceMatcher(a=DCM_CT, b=DCM_MR)
|
||||
match = matcher.find_longest_match(0, len(matcher.a), 0, len(matcher.b))
|
||||
ROOT_DIR = DCM_CT[:match.size]
|
||||
NII_DIR = os.path.join(ROOT_DIR, 'nii')
|
||||
INPUT_DIR = os.path.join(ROOT_DIR, 'input')
|
||||
OUTPUT_DIR = os.path.join(ROOT_DIR, 'output')
|
||||
|
||||
head, tail = os.path.split(DCM_CT)
|
||||
rtss_file = os.path.join(head, tail+'-rtss.dcm')
|
||||
|
||||
shutil.rmtree(NII_DIR, ignore_errors=True)
|
||||
os.makedirs(NII_DIR)
|
||||
shutil.rmtree(INPUT_DIR, ignore_errors=True)
|
||||
os.makedirs(INPUT_DIR)
|
||||
shutil.rmtree(OUTPUT_DIR, ignore_errors=True)
|
||||
# os.makedirs(OUTPUT_DIR)
|
||||
|
||||
nCT = os.path.basename(DCM_CT)
|
||||
nMR = os.path.basename(DCM_MR)
|
||||
|
||||
# print(nCT, nMR)
|
||||
# exit()
|
||||
|
||||
dcm2nii(DCM_CT, NII_DIR)
|
||||
dcm2nii(DCM_MR, NII_DIR)
|
||||
|
||||
for e in os.scandir(NII_DIR):
|
||||
if e.name.endswith('.nii.gz'):
|
||||
if e.name.startswith(nCT+'_'):
|
||||
NII_CT = e.path
|
||||
elif e.name.startswith(nMR+'_'):
|
||||
NII_MR = e.path
|
||||
|
||||
basename = os.path.basename(NII_MR)
|
||||
old = '_'+basename.split('_')[-1]
|
||||
input_file = os.path.join(INPUT_DIR, basename.replace(old, '_0000.nii.gz'))
|
||||
output_file = os.path.join(OUTPUT_DIR, basename.replace(old, '.nii.gz'))
|
||||
|
||||
|
||||
basename_ct = os.path.basename(NII_CT)
|
||||
old_ct = '_'+basename_ct.split('_')[-1]
|
||||
label_file = os.path.join(NII_DIR, basename_ct.replace(old_ct, '.label.nii.gz'))
|
||||
|
||||
shutil.copy(NII_MR, input_file)
|
||||
|
||||
print(NII_CT, NII_MR, input_file)
|
||||
|
||||
# nnUNet_predict -i INPUT_FOLDER -o OUTPUT_FOLDER -t 222 -m 3d_lowres --save_npz
|
||||
subprocess.run(["nnUNet_predict",
|
||||
"-i", INPUT_DIR,
|
||||
"-o", OUTPUT_DIR,
|
||||
"-t", "222",
|
||||
"-m", "3d_lowres",
|
||||
"--save_npz",
|
||||
])
|
||||
|
||||
print(output_file)
|
||||
|
||||
r2 = itk_elastix.register(NII_CT, NII_MR)
|
||||
itk_elastix.transform_write(output_file, r2['fwdtransforms'], label_file, is_label=True)
|
||||
|
||||
reader = sitk.ImageSeriesReader()
|
||||
dicom_names = reader.GetGDCMSeriesFileNames(DCM_CT)
|
||||
reader.SetFileNames(dicom_names)
|
||||
reader.MetaDataDictionaryArrayUpdateOn()
|
||||
reader.LoadPrivateTagsOn()
|
||||
image = reader.Execute()
|
||||
|
||||
nnU = sitk.ReadImage(label_file)
|
||||
nnU = sitk.Resample(nnU, image, sitk.Transform(), sitk.sitkNearestNeighbor)
|
||||
|
||||
ccfilter = sitk.ConnectedComponentImageFilter ()
|
||||
nnUCC = ccfilter.Execute(nnU)
|
||||
ObjectCount1 = ccfilter.GetObjectCount()
|
||||
|
||||
rtstruct = RTStructBuilder.create_new(dicom_series_path=DCM_CT)
|
||||
|
||||
for j1 in range(ObjectCount1):
|
||||
label1 = sitk.BinaryThreshold(nnUCC, j1+1, j1+1)
|
||||
# label1 = sitk.AntiAliasBinary(label1)
|
||||
|
||||
mask = sitk.GetArrayFromImage(label1).astype(bool)
|
||||
mask = np.transpose(mask, (1, 2, 0))
|
||||
# continue
|
||||
if mask.any():
|
||||
print(j1)
|
||||
rtstruct.add_roi(
|
||||
mask=mask,
|
||||
# use_pin_hole=True,
|
||||
# name="n%d"%n,
|
||||
)
|
||||
|
||||
print(rtss_file)
|
||||
rtstruct.save(rtss_file)
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print('Usage:', sys.argv[0], 'DCM_CT', 'DCM_MR')
|
||||
sys.exit()
|
||||
print('hello')
|
||||
print(sys.argv[0])
|
||||
print(sys.argv[1])
|
||||
|
||||
start = time.time()
|
||||
register(sys.argv[1], sys.argv[2])
|
||||
end = time.time()
|
||||
print(end - start, 'seconds')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
59
3-send.py
Executable file
59
3-send.py
Executable file
|
@ -0,0 +1,59 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from pydicom import dcmread
|
||||
|
||||
from pynetdicom import AE, debug_logger
|
||||
from pynetdicom.sop_class import CTImageStorage, RTStructureSetStorage
|
||||
|
||||
debug_logger()
|
||||
|
||||
def SendDCM(fp):
|
||||
|
||||
# Initialise the Application Entity
|
||||
ae = AE()
|
||||
ae.ae_title = 'OUR_STORE_SCP'
|
||||
|
||||
# Add a requested presentation context
|
||||
# ae.add_requested_context(CTImageStorage)
|
||||
ae.add_requested_context(RTStructureSetStorage)
|
||||
|
||||
# Read in our DICOM CT dataset
|
||||
ds = dcmread(fp)
|
||||
|
||||
# Associate with peer AE at IP 127.0.0.1 and port 11112
|
||||
assoc = ae.associate("127.0.0.1", 11112)
|
||||
assoc = ae.associate("172.16.40.36", 104,
|
||||
ae_title = 'N1000_STORAGE',
|
||||
)
|
||||
if assoc.is_established:
|
||||
# Use the C-STORE service to send the dataset
|
||||
# returns the response status as a pydicom Dataset
|
||||
status = assoc.send_c_store(ds)
|
||||
|
||||
# Check the status of the storage request
|
||||
if status:
|
||||
# If the storage request succeeded this will be 0x0000
|
||||
print('C-STORE request status: 0x{0:04x}'.format(status.Status))
|
||||
else:
|
||||
print('Connection timed out, was aborted or received invalid response')
|
||||
|
||||
# Release the association
|
||||
assoc.release()
|
||||
else:
|
||||
print('Association rejected, aborted or never connected')
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print('Usage:', sys.argv[0], 'RTSS')
|
||||
sys.exit()
|
||||
print('hello')
|
||||
print(sys.argv[0])
|
||||
print(sys.argv[1])
|
||||
SendDCM(sys.argv[1])
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
35
docker/Dockerfile
Executable file
35
docker/Dockerfile
Executable file
|
@ -0,0 +1,35 @@
|
|||
FROM nvcr.io/nvidia/clara-train-sdk:v4.1
|
||||
|
||||
# apt
|
||||
RUN apt-get update -y \
|
||||
&& apt-get install dcm2niix openssh-server pigz sudo -y
|
||||
|
||||
# pip
|
||||
# RUN pip install antspyx itk-elastix nipype nnunet rt_utils
|
||||
RUN pip install antspyx itk-elastix nnunet # too large .... install first
|
||||
RUN pip install --upgrade git+https://github.com/FabianIsensee/hiddenlayer.git@more_plotted_details#egg=hiddenlayer
|
||||
RUN pip install git+https://github.com/qurit/rt-utils.git@5bab9ffcc8fe19dd775e940afdc3d8f48f869150 # fix FrameOfReferenceUID
|
||||
RUN pip install masonite nipype
|
||||
|
||||
# nnUNet
|
||||
|
||||
ENV nnUNet_raw_data_base="/workspace/nnUNet_raw_data_base"
|
||||
ENV nnUNet_preprocessed="/workspace/nnUNet_preprocessed"
|
||||
ENV RESULTS_FOLDER="/workspace/nnUNet_trained_models"
|
||||
|
||||
# SSH server
|
||||
#RUN echo 'root:password' | chpasswd
|
||||
#RUN echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config
|
||||
#RUN echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
|
||||
#ENTRYPOINT service ssh restart && env >> /etc/environment && bash
|
||||
#EXPOSE 22
|
||||
|
||||
# jupyter
|
||||
ENTRYPOINT jupyter-lab
|
||||
EXPOSE 8888
|
||||
|
||||
# pynetdicom
|
||||
EXPOSE 11120
|
||||
|
||||
# WORKDIR /workspace
|
||||
WORKDIR /123
|
1
docker/build.sh
Executable file
1
docker/build.sh
Executable file
|
@ -0,0 +1 @@
|
|||
DOCKER_BUILDKIT=1 docker build -t 123:v0 .
|
14
docker/qrun.sh
Executable file
14
docker/qrun.sh
Executable file
|
@ -0,0 +1,14 @@
|
|||
#DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
#DIR="$(dirname $( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd ))"
|
||||
|
||||
export dockerImage=123:v0
|
||||
|
||||
#docker run --gpus all --ipc=host --ulimit memlock=-1 --ulimit stack=67108864 -it --rm -v $DIR:/workspace $dockerImage /bin/bash
|
||||
GPU=nvidia0 gpu-docker run --ipc=host --ulimit memlock=-1 --ulimit stack=67108864 -it --rm \
|
||||
-v /share/WORKSPACE/nnUNet:/workspace \
|
||||
-v /share/Public/git/123:/123 \
|
||||
-v /share/Public/git/123:/root \
|
||||
-v /share/Public/nn:/nn \
|
||||
-p 11120:11120 \
|
||||
-p 8888:8888 \
|
||||
$dockerImage &
|
302
itk_elastix.py
Normal file
302
itk_elastix.py
Normal file
|
@ -0,0 +1,302 @@
|
|||
from pprint import pprint
|
||||
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
|
||||
from skimage.metrics import normalized_mutual_information
|
||||
|
||||
import itk
|
||||
|
||||
metric_patern = r'Final metric value = (\S+)'
|
||||
metric_prog = re.compile(metric_patern)
|
||||
|
||||
|
||||
'''
|
||||
ants.registration.interface
|
||||
|
||||
myiterations = '2100x1200x1200x10'
|
||||
'''
|
||||
# MaximumNumberOfIterations = ['1200']
|
||||
# MaximumNumberOfIterations = ['2100']
|
||||
|
||||
# NumberOfIterations = 1200
|
||||
NumberOfIterations = 2100
|
||||
# NumberOfIterations = 4000
|
||||
|
||||
def register_aux(fi, mv, debug=False, MaximumNumberOfIterations=[str(NumberOfIterations)]):
|
||||
|
||||
parameter_object = itk.ParameterObject.New()
|
||||
default_rigid_parameter_map = parameter_object.GetDefaultParameterMap('rigid')
|
||||
default_rigid_parameter_map["AutomaticTransformInitialization"] = ["true"]
|
||||
# default_rigid_parameter_map["NumberOfSamplesForExactGradient"] = ["100000"]
|
||||
default_rigid_parameter_map['MaximumNumberOfIterations'] = MaximumNumberOfIterations
|
||||
parameter_object.AddParameterMap(default_rigid_parameter_map)
|
||||
|
||||
# pprint(default_rigid_parameter_map.asdict())
|
||||
# exit()
|
||||
|
||||
outdir1 = tempfile.mkdtemp()
|
||||
|
||||
try:
|
||||
fm, params1 = itk.elastix_registration_method(
|
||||
fi, mv,
|
||||
parameter_object=parameter_object,
|
||||
# log_to_console=True,
|
||||
log_to_file=True,
|
||||
output_directory = outdir1,
|
||||
)
|
||||
except Exception as ex:
|
||||
print(ex)
|
||||
print(os.path.join(outdir1, 'elastix.log'))
|
||||
# exit()
|
||||
return {
|
||||
'metrics': 0,
|
||||
}
|
||||
|
||||
TransformParameterFileName = os.path.join(outdir1, 'TransformParameters.0.txt')
|
||||
|
||||
# print(TransformParameterFileName)
|
||||
# exit()
|
||||
|
||||
'''
|
||||
The DisplacementMagnitudePenalty is a cost function that penalises ||Tμ(x) − x||2. You can use this
|
||||
to invert transforms, by setting the transform to be inverted as an initial transform (using -t0), setting
|
||||
(HowToCombineTransforms "Compose"), and running elastix with this metric, using the original fixed
|
||||
image set both as fixed (-f) and moving (-m) image. After that you can manually set the initial transform
|
||||
in the last parameter file to "NoInitialTransform", and voila, you have the inverse transform! Strictly
|
||||
speaking, you should then also change the Size/Spacing/Origin/Index/Direction settings to match that of
|
||||
the moving image. Select it with:
|
||||
(Metric "DisplacementMagnitudePenalty")
|
||||
Note that inverting a transformation becomes conceptually very similar to performing an image registration
|
||||
in this way. Consequently, the same choices are relevant: optimisation algorithm, multiresolution etc...
|
||||
Note that this procedure was described and evaluated in Metz et al. [2011].
|
||||
'''
|
||||
|
||||
parameter_object2 = itk.ParameterObject.New()
|
||||
inverse_rigid_parameter_map = parameter_object.GetDefaultParameterMap('rigid')
|
||||
inverse_rigid_parameter_map["HowToCombineTransforms"] = ["Compose"]
|
||||
inverse_rigid_parameter_map["Metric"] = ["DisplacementMagnitudePenalty"]
|
||||
|
||||
# inverse_rigid_parameter_map["AutomaticTransformInitialization"] = ["true"]
|
||||
inverse_rigid_parameter_map['MaximumNumberOfIterations'] = MaximumNumberOfIterations
|
||||
# inverse_rigid_parameter_map['UseAdaptiveStepSizes'] = ['false']
|
||||
parameter_object2.AddParameterMap(inverse_rigid_parameter_map)
|
||||
|
||||
|
||||
# print(TransformParameterFileName)
|
||||
# exit()
|
||||
|
||||
|
||||
outdir2 = tempfile.mkdtemp()
|
||||
mm, params2 = itk.elastix_registration_method(
|
||||
mv, mv,
|
||||
parameter_object=parameter_object2,
|
||||
initial_transform_parameter_file_name = TransformParameterFileName,
|
||||
log_to_console=debug,
|
||||
log_to_file=True,
|
||||
output_directory = outdir2,
|
||||
)
|
||||
|
||||
elastix_log = os.path.join(outdir2, 'elastix.log')
|
||||
with open(elastix_log) as log:
|
||||
m = re.search(metric_prog, log.read())
|
||||
|
||||
DisplacementMagnitudePenalty = float(m[1])
|
||||
# print(DisplacementMagnitudePenalty)
|
||||
# exit()
|
||||
|
||||
last_parameter_map = params2.GetParameterMap(0)
|
||||
# pprint(last_parameter_map.asdict())
|
||||
# exit()
|
||||
last_parameter_map["InitialTransformParametersFileName"] = ["NoInitialTransform"]
|
||||
|
||||
params2.SetParameterMap(0, last_parameter_map)
|
||||
# params2.WriteParameterFile('123.txt')
|
||||
mf = itk.transformix_filter(
|
||||
fi,
|
||||
params2)
|
||||
|
||||
m1 = normalized_mutual_information(itk.GetArrayViewFromImage(fi), itk.GetArrayViewFromImage(fm))
|
||||
m2 = normalized_mutual_information(itk.GetArrayViewFromImage(mv), itk.GetArrayViewFromImage(mf))
|
||||
|
||||
print(MaximumNumberOfIterations, m1, m2, DisplacementMagnitudePenalty)
|
||||
|
||||
shutil.rmtree(outdir1)
|
||||
shutil.rmtree(outdir2)
|
||||
# exit()
|
||||
|
||||
|
||||
return {
|
||||
'fwdtransforms': params1,
|
||||
'invtransforms': params2,
|
||||
'warpedfixout': mf,
|
||||
'warpedmovout': fm,
|
||||
'metrics': max(m1, m2),
|
||||
'DisplacementMagnitudePenalty': DisplacementMagnitudePenalty,
|
||||
}
|
||||
|
||||
|
||||
PixelType = itk.F
|
||||
Dimension = 3
|
||||
ImageType = itk.Image[PixelType, Dimension]
|
||||
# reader = itk.ImageFileReader[ImageType].New()
|
||||
# reader.SetFileName("image.tif")
|
||||
# reader.Update()
|
||||
# image = reader.GetOutput()
|
||||
|
||||
|
||||
# METRIC_THRESHOLD = 1.1
|
||||
def register(fi, mv, warpedfixout=None, warpedmovout=None, debug=False, iterations_init=NumberOfIterations):
|
||||
|
||||
# reader = itk.ImageFileReader[ImageType].New()
|
||||
# reader.SetFileName(fi)
|
||||
# reader.Update()
|
||||
# fixed_image = reader.GetOutput()
|
||||
|
||||
fixed_image = itk.imread(fi, itk.F)
|
||||
moving_image = itk.imread(mv, itk.F)
|
||||
|
||||
iterations = iterations_init
|
||||
# iterations_fin = iterations_init*2
|
||||
|
||||
|
||||
while True:
|
||||
MaximumNumberOfIterations = [str(iterations)]
|
||||
r1 = register_aux(fixed_image, moving_image, debug, MaximumNumberOfIterations=MaximumNumberOfIterations)
|
||||
|
||||
if 'DisplacementMagnitudePenalty' not in r1: # None?
|
||||
break
|
||||
if r1['DisplacementMagnitudePenalty'] < 1:
|
||||
break
|
||||
# elif r1['metrics'] > METRIC_THRESHOLD:
|
||||
# Redo = False
|
||||
|
||||
# if iterations>iterations_fin:
|
||||
# Redo = False
|
||||
|
||||
iterations *= 2
|
||||
|
||||
|
||||
while True:
|
||||
MaximumNumberOfIterations = [str(iterations)]
|
||||
r2 = register_aux(moving_image, fixed_image, debug, MaximumNumberOfIterations=MaximumNumberOfIterations)
|
||||
|
||||
if 'DisplacementMagnitudePenalty' not in r2: # None?
|
||||
break
|
||||
elif r2['DisplacementMagnitudePenalty'] < 1:
|
||||
break
|
||||
# elif r2['metrics'] > METRIC_THRESHOLD:
|
||||
# Redo = False
|
||||
|
||||
# if iterations>iterations_fin:
|
||||
# Redo = False
|
||||
|
||||
iterations *= 2
|
||||
|
||||
|
||||
|
||||
if r1['metrics'] > r2['metrics']:
|
||||
res = r1
|
||||
else:
|
||||
|
||||
if 'invtransforms' not in r2:
|
||||
return None
|
||||
|
||||
res = dict(r2)
|
||||
res.update({
|
||||
'fwdtransforms': r2['invtransforms'],
|
||||
'invtransforms': r2['fwdtransforms'],
|
||||
'warpedfixout': r2['warpedmovout'],
|
||||
'warpedmovout': r2['warpedfixout'],
|
||||
})
|
||||
|
||||
|
||||
assert res['DisplacementMagnitudePenalty'] < 1, 'DisplacementMagnitudePenalty: %f ' % (res['DisplacementMagnitudePenalty'])
|
||||
|
||||
|
||||
if warpedfixout is not None:
|
||||
itk.imwrite(res['warpedfixout'], warpedfixout)
|
||||
if warpedmovout is not None:
|
||||
itk.imwrite(res['warpedmovout'], warpedmovout)
|
||||
|
||||
if debug:
|
||||
pprint(res)
|
||||
itk.imwrite(fixed_image, '0fixed.nii.gz')
|
||||
itk.imwrite(moving_image, '0moving.nii.gz')
|
||||
itk.imwrite(r1['warpedfixout'], '0mf1.nii.gz')
|
||||
itk.imwrite(r1['warpedmovout'], '0fm1.nii.gz')
|
||||
itk.imwrite(r2['warpedmovout'], '0mf2.nii.gz')
|
||||
itk.imwrite(r2['warpedfixout'], '0fm2.nii.gz')
|
||||
|
||||
return res
|
||||
|
||||
def transform_write(moving, transform, output_filename, is_label=False):
|
||||
mv = itk.imread(moving)
|
||||
|
||||
last_parameter_map = transform.GetParameterMap(0)
|
||||
|
||||
if is_label:
|
||||
# last_parameter_map["InitialTransformParametersFileName"] = ["NoInitialTransform"]
|
||||
last_parameter_map["ResampleInterpolator"] = ["FinalNearestNeighborInterpolator"]
|
||||
# last_parameter_map["ResultImagePixelType"] = ["unsigned char"]
|
||||
|
||||
t2 = itk.ParameterObject.New()
|
||||
t2.AddParameterMap(last_parameter_map)
|
||||
# pprint(t2.GetParameterMap(0).asdict())
|
||||
|
||||
output = itk.transformix_filter(
|
||||
mv.astype(itk.F),
|
||||
t2)
|
||||
|
||||
if is_label:
|
||||
output=output.astype(itk.UC)
|
||||
itk.imwrite(output, output_filename)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
fi = '/media/nfs/SRS/TSGH2022G4/register_fwd/2131720/case2017.04.21.11.01.48/patient_6_RT_Cyberknife_1mm_Head_20170420091131_3.nii.gz'
|
||||
mv = '/media/nfs/SRS/TSGH2022G4/register_fwd/2131720/case2017.04.21.11.01.48/patient_T1_SE_GD_20170420102216_3.nii.gz'
|
||||
|
||||
|
||||
fi = '/media/nfs/SRS/TSGH2022G4/image/2131720/patient_6_RT_Cyberknife_1mm_Head_20170420091131_3.nii.gz'
|
||||
mv = '/media/nfs/SRS/TSGH2022G4/image/2131720/patient_T1_SE_GD_20170420102216_3.nii.gz'
|
||||
|
||||
fi = '/media/nfs/SRS/TSGH2022G4/image/1693329/patient_6_Head_CTA_CNY_Head_20100330100138_18.nii.gz'
|
||||
mv = '/media/nfs/SRS/TSGH2022G4/image/1693329/patient_T1_SE_GD_20100330105831_3.nii.gz'
|
||||
|
||||
|
||||
# 4D image
|
||||
# fi = '/media/nfs/SRS/NTUH2022G4/image/6053604/patient_1.7_CTA_+_Perfusion_(Subtraction)_20140121125458_103.nii.gz'
|
||||
# mv = '/media/nfs/SRS/NTUH2022G4/image/6053604/patient_AX_T1+C(3D_2MM)_ZIP_512_20140121105711_5.nii.gz'
|
||||
|
||||
# bad registraation
|
||||
fi = '/media/nfs/SRS/TSGH2022G4/image/2978108/patient_6_RT_Cyberknife_1mm_Head_20170608103902_3.nii.gz'
|
||||
mv = '/media/nfs/SRS/TSGH2022G4/image/2978108/patient_Ax_T1_SE_CK_GD+_20170608094843_4.nii.gz'
|
||||
|
||||
fi = '/media/nfs/SRS/TSGH2022G4/image/2511774/patient_6_RT_Cyberknife_1mm_Head_20141215144427_3.nii.gz'
|
||||
mv = '/media/nfs/SRS/TSGH2022G4/image/2511774/patient_T1_SE_GD_20141215140945_3.nii.gz'
|
||||
|
||||
fi = '/media/nfs/SRS/TSGH2022G4/image/2305719/patient_6_RT_Cyberknife_1mm_Head_20090519105710_4.nii.gz'
|
||||
mv = '/media/nfs/SRS/TSGH2022G4/image/2305719/patient_T1_SE_GD_20090519104815_3.nii.gz'
|
||||
|
||||
|
||||
# insufficent inverse
|
||||
fi = '/media/nfs/SRS/TSGH2022G4/image/2441399/patient_2_Liver_3Phase_CK_Abdomen_20111031104910_9_e1.nii.gz'
|
||||
mv = '/media/nfs/SRS/TSGH2022G4/image/2441399/patient_6_RT_Cyberknife_1mm_Head_20120625103934_3.nii.gz'
|
||||
|
||||
fi = '/media/nfs/SRS/TSGH2022G4/image/2232394/patient_6_RT_Cyberknife_1mm_Head_20100222122239_3.nii.gz'
|
||||
mv = '/media/nfs/SRS/TSGH2022G4/image/2232394/patient_6_RT_Cyberknife_1mm_Head_20100222092318_4.nii.gz'
|
||||
|
||||
|
||||
fi = '/media/nfs/SRS/TSGH2022G4/image/1255468/patient_6_RT_Cyberknife_1mm_Head_20080417105648_3.nii.gz'
|
||||
mv = '/media/nfs/SRS/TSGH2022G4/image/1255468/patient_ebrain_IR_T1_ax_GD_20110209152748_1102.nii.gz'
|
||||
|
||||
|
||||
# r = register(fi, mv, debug=True)
|
||||
r = register(fi, mv)
|
||||
|
||||
print(r)
|
Loading…
Reference in a new issue