SuperElastix / SimpleElastix

Multi-lingual medical image registration library
http://simpleelastix.github.io
Apache License 2.0
509 stars 149 forks source link

(0x4465e80): Too many samples map outside moving image buffer: 784 / 4096 #403

Open black0017 opened 3 years ago

black0017 commented 3 years ago

Hello,

What I have tried:

I am registering a dataset of CBCT's to CT. While I have 80 patients with multiple CBCT for each one, for two patients I get this error:

Error log:

itk::ExceptionObject (0x3d6c550)
Location: "ElastixTemplate - Run()" 
File: /home/utilisateur/build/Elastix/Common/CostFunctions/itkAdvancedImageToImageMetric.hxx
Line: 1007
Description: itk::ERROR: AdvancedMattesMutualInformationMetric(0x4465e80): **Too many samples map outside moving image buffer: 784 / 4096**

Error occurred during actual registration.

I resized the CT image to the CBCT so that they have the same spatial dimensions. It's very strange that this error shows up only for registration in the whole dataset

How can I possibly fix this issue?

Thanks

velonica0 commented 2 years ago

How did you solve this problem, is it because the resolution of the two pictures is different?

black0017 commented 2 years ago

Hi @velonica0 , to be honest I don't remember, it's been a long time, but image resolutions was not the problem. I guess it had to do with the "empty" slices on my CBCT image but i really cannot recall.

I used the following 3 functions please take a look and see if something is useful to you:

import os

import SimpleITK as sitk
import numpy as np

def register_and_save(ref_img, moving_CBCT_path, save_path, debug=False):
    mov_img = sitk.ReadImage(moving_CBCT_path)
    # print('cbct shape:',sitk.GetArrayFromImage(mov_img).shape)
    # print('ct shape:',sitk.GetArrayFromImage(ref_img).shape)

    resultImage = register(ref_img, mov_img, reg_type='translation',debug=debug)

    print('resulted img shape:', sitk.GetArrayFromImage(resultImage).shape)
    result_np = sitk.GetArrayFromImage(resultImage)
    #result_np = delete_empy_slices(result_np)
    resultImage = sitk.GetImageFromArray(result_np)

    save_nifty(resultImage, save_path, moving_CBCT_path)

def register(ref_img, mov_img, reg_type='translation', debug=False):
    # "affine" and 'translation' is supported
    parameterMap = sitk.GetDefaultParameterMap(reg_type)
    parameterMap['DefaultPixelValue'] = ['-1000']  # AIR in Housenfield units
    parameterMap['MaximumNumberOfIterations'] = ['512']  # more iteration for better convergence

    if debug:
        itk_filter = sitk.ElastixImageFilter()
        itk_filter.LogToConsoleOn()  #debug
        itk_filter.LogToFileOn()  #debug
        itk_filter.SetFixedImage(ref_img)
        itk_filter.SetMovingImage(mov_img)
        itk_filter.SetParameterMap(parameterMap)
        resultImage = itk_filter.Execute()
    else:
        resultImage = sitk.Elastix(ref_img, mov_img, parameterMap)
    return resultImage

def delete_empy_slices(result_np):
    slices = result_np.shape[0]
    mean_val_per_slice = np.mean(result_np, axis=1).mean(axis=1)
    # print(mean_val_per_slice.shape)
    non_empty_slices = []
    for i in range(slices):
        if mean_val_per_slice[i] >= -900:
            non_empty_slices.append(result_np[i, ...])
    print('len non empty slices:', len(non_empty_slices), '/',mean_val_per_slice.shape[0])
    cropped_img = np.asarray(non_empty_slices)
    return cropped_img

Best :)

mathiser commented 1 year ago

For anyone with the same issue - this error disappeared for me when increasing parameterMap['MaximumNumberOfIterations'] = ['512'] from the default