Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

Инструмент для совмещения трехмерных изображений.

Данный проект представляет собой гибкий конфигурируемый инструмент для совмещения трехмерных изображений. В основе инструмента лежит использование открытой библиотеки SITK для поиска преобразования, приводящего два 3D изображения в общие координаты. Инструмент также позволяет применять найденное преобразование, сохранять преобразованные объемы в общих координатах как набор мультиканальных двумерных изображений, задавать начальное приближение в виде матрицы или интерактивным выделением особых точек и выполнять оценку качества совмещения в случае известного идеального преобразования. Репозиторий содержит также пример структуры папок для работы с данными, тестовые данные, инструкцию по использованию и запуску инструмента на тестовом примере для Windows 10.

Для ОС Arch Linux. Работа инструмента совмещения так же возможна на операционной системе Arch Linux и подобных ей.

Важно! В случае Arch Linux можно использовать данную инструкцию, отличие присутствует только в команде активации виртуального окружения для терминала (пункт 2).

Конфигурация виртуального окружения для работы прогонщика.

Для настройки виртуального окружения необходимо проделать следующие шаги:

  1. Необходимо клонировать репозиторий или отдельно скачать файл required_libraries.txt из папки runner репозитория.

  2. Создать чистое виртуальное окружение с помощью virtualenv:

python -m venv venv_name

Также можно воспользоваться conda .

  1. Активировать окружение:
path\to\venv_name\Scripts\activate.bat
Для ОС Arch Linux.
path\to\venv_name\bin\activate
  1. Запустить в терминале из папки с файлом required_libraries.txt команду
pip install -r required_libraries.txt

Работа с инструментом совмещения.

Структура папок

Для работы с инструментом рекомендуется создать структуру папок и файлов следующего вида (пример такой структуры представлен в репозитории, поэтому его можно клонировать и использовать после настройки конфигов):

  • runner
    • experiment_runner.py
    • metrics.py
    • parser.py
    • registration_gui.py
    • required_libraries.txt
    • results_visualization.py
    • sample_creator.py
    • SITK.py
  • experiments
    • example_algorithms_configs
      • sitk_config.json
      • test_experiment_config_0.json
      • test_experiment_config_1.json
    • test_data
      • data1
        • ...
      • data2
        • ...
    • ...

Важно! В папке runner (может иметь любое название) обязательно должны содержатся все файлы c исходным кодом для запуска совмещения, а также файл required_libraries.txt с необходимыми библиотеками.

Папка experiments (может иметь любое название) - это папка, содержащая результаты экспериментов по совмещению. Все эксперименты рекомендуется делать в основной папке experiments, но можно и каждый раз указывать путь до произвольной папки. В выбранной пользователем директории при каждом запуске эксперимента алгоритм автоматически создает папку с заданным пользователем названием эксперимента и сохраняет в нее результаты, копии всех конфигурационных файлов, необходимых для точного повторения эксперимента, и временные файлы, создаваемые в процессе работы алгоритма.

Также в приведенном в репозитории примере в папке experiments есть папка example_algorithms_configs (может иметь любое название), содержащая примеры конфига метода SITK и конфигов экспериментов. Конфигов метода может быть сколько угодно - для каждого эксперимента может быть свой, либо же один конфиг метода может использоваться для нескольких экспериментов. Расположение конфигов методов указывается в конфиге эксперимента, а расположение конфига эксперимента указывается пользователем при запуске инструмента совмещения. При запуске каждого нового эксперимента копии указанных конфига метода и конфига эксперимента сохраняются вместе с результатами, что позволяет редактировать один и тот же конфигурационный файл и использовать его для разных экспериментов без потери информации о конфигурации предыдущих. Поэтому конфиги могут иметь любое расположение, но для удобства папка example_algorithms_configs с ними добавлена в experiments.

Запуск тестовых примеров.

В репозитории содержатся тестовые данные, конфиги, результат работы инструмента совмещения. Ниже будет представлено объяснение процедуры настройки и запуска на примере структуры папок и данных в репозитории.

1. Выкачивание репозитория.

Для начала необходимо выкачать или клонировать данный репозиторий. Для запуска тестовых примеров необходимо распаковать тестовые данные, содержащие реконструкцию грецкого ореха по слоям в изображениях формата .tif, и удалить архивы.

В репозитории представлено два эксперимента с парами данных в первом nut и nut_rotated (повернутый nut) и во втором nut и nut_enlarged (увеличенный в 1.5 раза nut).

2. Настройка конфигов экспериментов.

Для запуска примеров необходимо настроить конфиги экспериментов.

Описание параметров конфига эксперимента.
{   "path_to_results_inf" : "Путь до папки, в которой автоматически будет создана директория с данными, полученными в результате работы алгоритма (experiments в репозитории).",
    "path_to_results" : "/path/to/experiments/",

    "experiment_name_info" : ["Для каждого эксперимента создается папка с его названием, взятым из поля experiment_name. Туда во время запуска алгоритма автоматически копируется текущий конфиг эксперимента и конфиг алгоритма с пометкой времени запуска. Так же в эту папку будут записаны все данные, полученные в результате работы алгоритма.",
                  "Если в папке path_to_results уже существует папка с названием experiment_name, то при новом запуске с тем же самым experiment_name алгоритм автоматически создаст папку с именем experiment_name_001, затем experiment_name_002 и так далее"],
    "experiment_name" : "test_example_0",

    "algorithm_name_info" : "Задает название папки, НЕ МЕТОД, метод задается исполняемым файлом и конфигом с настройками.",
    "algorithm_name" : "sitk",
    "algorithm_name_examples" : {
        "1" : "sitk",
        "2" : "sith",
        "3" : "any_convenient_name_for_the_method"
    },

    "algorithm_execution_parameters_path_info" : "Путь до конфига метода, может иметь любое расположение и название.",
    "algorithm_execution_parameters_path" : "/path/to/experiments/example_algorithms_configs/sitk_config.json",

    "algorithm_executable_path_info" : "Путь до скрипта с методом.", 
    "algorithm_executable_path" : "/path/to/runner/SITK.py",

    "alg_interpreter_path_info" : "Путь до файла python.exe вашего окружения.",
    "alg_interpreter_path" : "/path/to/venv_name/Scripts/python.exe",

    "VolumeLoadingMode_info" : "Не изменять.",
    "VolumeLoadingMode" : "TwoVolumes",

    "registered_volumes_writing_info" : ["Флаг для сохранения результата совмещения.",
                                         "Если указать false, то полученные в результате совмещения объёмы не будут отписываться в тифы, записанными останутся только параметры найденного преобразования (его прямая и обратная матрицы)."],
    "registered_volumes_writing" : true,

    "minimize_padding_info" : ["Флаг для выбора области интереса при сохранении результата совмещения.",
                               "Если указать false, то полученные в результате совмещения объёмы будут представлять описанный прямоугольный параллелепипед вокруг результирующего совмещения целевого и изменяемого объёмов (логическое объеденение объёмов). В таком случае добавленные воксели без соответствующих значений интенсивностей в исходных объёмах будут иметь 0  значения интенсивности.",
                               "Если указать true, то то полученные в результате совмещения объёмы будут отображать пересечение результирующего совмещения целевого и изменяемого объёмов с областью целевого объёма"],
    "minimize_padding" : true,

    "calculate_metrics_info" : "Флаг для вычисления метрик - для вычисления значения всех предложенных метрик, кроме MSE, нужно указать эталонное преобразование в поле ниже",
    "calculate_metrics" : false,

    "path_to_gt_matrix_json_info" : "Путь до json файла с матрицей эталонного преобразования (примеры есть в репозитории в nut_rotated.rar и в nut_enlarged.rar).",
    "path_to_gt_matrix_json" : "",

    "SelectedVisualizedMetricsList_info" : "Метрики, которые будут рассчитываться, если включен флаг calculate_metrics. Можно исключить из списка ненужные и оставить только необходимые.",
    "SelectedMetricsList" : ["MSE",
                             "normalized maximum deviation of distances (from geometry MSE)",
                             "maximum deviation of distances (from geometry MSE)",
                             "norm_geometry_rmse",
                             "geometry_rmse",
                             "norm_geometry_MSE"],

    "path_to_markup_info" : "Путь до целевого объема, к которому будет приводится объем moving, может иметь любое расположение.",
    "path_to_markup" : "/path/to/experiments/test_data/nut/",

    "path_to_moving_info" : "Путь до изменяемого объема, преобразуемый для приведения в координаты целевого объёма markup, может иметь любое расположение.",
    "path_to_moving" : "/path/to/experiments/test_data/nut_rotated/",

    "path_to_initial_transform_matrix_json_info" : ["Путь до .json с начальным преобразованием, которое будет доуточняться методом (преобразование из moving в markup).",
                                                   "Пример json'a с нач. преобразованием содержится в папке тестового объема nut_rotated."], 
    "path_to_initial_transform_matrix_json" : "/path/to/experiments/test_data/nut_rotated/initial_matrix.json" 
}

Для запуска тестового примера настройку конфига метода производить не надо, описание полей конфига метода будет ниже.

Важно! Для использования матрицы начального преобразования, записанного в initial_matrix.json, в конфиге метода sitk_config.json в поле InitialTransform необходимо указать значение MATRIX.

3. Запуск экспериментов.

После скачивания репозитория, настройки окружения, распаковки архивов в папке test_data и настройки конфигов экспериментов можно запустить тестовые эксперименты.

Из папки runner в консоли запустите эксперимент №0 (предварительно в конфиге метода sitk_config.json в поле InitialTransform необходимо указать значение MOMENTS, а InitialTransformViewer - false)

python experiment_runner.py /path/to/experiments/example_algorithms_configs/test_experiment_config_0.json

Аналогично, эксперимент №1 (предварительно в конфиге метода sitk_config.json в поле InitialTransform необходимо указать значение MATRIX, а InitialTransformViewer - true)

python experiment_runner.py /path/to/experiments/example_algorithms_configs/test_experiment_config_1.json

4. Результаты.

После завершения работы алгоритма в выбранной в конфиге эксперимента папке для сохранения результатов (в тестовых конфигах это папка experiments) будет создана папка с названием эксперимента (в случае использования тестовых конфигов это папка test_example_0 и test_example_1 для тестовых экспериментов №0 и №1 соответственно). В ней будут созданы: папка processing с промежуточными файлами, необходимыми методу, папка sitk_ГГГГ_ММ_ДД_ЧЧ_ММ_СС_configs с копиями конфигов эксперимента и метода, папка stitching_results, в которой сохранятся основные результаты совмещения: padded_markup_0 и padded_test_0 это объемы одинакового размера, приведенные к одному масштабу, ориентации, смещению; colored_joining_volume_0 - исходное и преобразованное изображения записаные в R и GB каналах RGB изображения соответственно для демонстрации различий; папка metrics, в которой находятся: matrices.json с прямой и обратной матрицами преобразования между объёмами, time_mem.json, содержащий информацию о времени выполнения алгоритма и затраченном максимальном количестве оперативной памяти, metrics.json, содержащий рассичтанные по результатам совмещения выбранные пользователем в конфигурационном файле метрики качества совмещения (если рассчёт метрик отключен соответствующим флагом в конфигурационном файле, но этот json отсутствует) и папка graphs, содержащая данные о положении оптимизатора (значения параметров оптимизируемого преобразования) на каждой итерации в процессе работы алгоритма. Основной результат эксперимента - это объемы в папках padded_markup_0 и padded_test_0 - их наложение позволяет получить совмещенный совместный объем, причем сделать это можно повоксельно - объемы специально приведены к одинаковым размерам.

Пример структуры папок с результатами тестового совмещения №0.
  • test_example_0
    • processing
      • sitk
        • custom_markup
          • alg_out_json.json
    • sitk_ГГГГ_ММ_ДД_ЧЧ_ММ_СС_configs
      • test_experiment_config_0.json
      • sitk_config.json
    • stitching_results
      • sitk
        • custom_markup
          • colored_joining_volume_0
          • metrics
            • 0
              • graphs
                • ...
              • matrices.json
              • metrics.json
              • time_mem.json
          • padded_markup_0
          • padded_test_0
          • test_transformed_0

Описание параметров метода SITK.

Указание типа пространственного преобразования для поиска алгоритмом SITK.

В начале необходимо выбрать класс пространственного преобразования, которое будет искать алгоритм SITK для совмещения исходных объёмов. Это позволяет ограничить степени свободы при оптимизации параметров преобразования алгоритмом.

В текущей версии реализован поиск преобразования подобия и аффинного преобразования:

  • Similarity - преобразование подобия с 7 степенями свободы: 1 степень свободы при изотропном масштабировании по всем трём направлениям, 3 вращательные степени свободы и 3 степени свободы при параллельном переносе;
  • Affine - аффинное преобразование с 12 степенями свободы: 3 степени свободы при анизотропном масштабировании, 3 вращательные степени свободы, 3 сдвиговых степени свободы и 3 степени свободы при параллельном переносе;
"TransformType": "Similarity"

Начальное преобразование SITK.

Одним из самых важных аспектов в работе SITK является начальное преобразование, которое данный метод будет уточнять в процессе работы.

Есть несколько доступных режимов работы по поиску начального преобразования:

  • GEOMETRY - геометрический центр одного трехмерного изображения приводится к геометрическому центру другого изображения, только преобразование смещения;
  • MOMENTS - центр масс одного трехмерного изображения приводится к центру масс другого изображения, только преобразование смещения;
  • POINTS - режим на основе ручной разметки особых точек;
  • MATRIX - начальное преобразование из объема moving в markup задается матрицей 4x4 в файле .json, этот способ был описан в предыдущем разделе Работа с прогонщиком;
  • MANUAL - ручная тонкая настройка преобразования в конфиге, позволяет отдельно задать масштаб, вращение (в порядке xyz), смещение (в порядке xyz), причем смещение задается либо вручную отдельно по каждой координате (режим MANUAL), либо с помощью описанных выше режимов GEOMETRY и MOMENTS.
"InitialTransform": "MOMENTS",
  "initial_transform_help": {
    "possible_options" : ["GEOMETRY", "MOMENTS", "POINTS", "MATRIX", "MANUAL"]
  },

"note" : ["Здесь фигурирует два разных значения MANUAL:",
         "одно относится к полю InitialTransform выше и задает ручной режим определения начального преобразования SITK,",
         "другое относится к полю InitialTranslationOption ниже - одно из полей настройки режима InitialTransform == MANUAL:",
         "автоматическое совмещение центров объемов (GEOMETRY),",
         "совмещение центров масс(MOMENTS)",
         "или же ручное задание 3 координат смещения (MANUAL)."],
"InitialTransformParams":{
    "info" : "при выборе InitialTransform == MANUAL параметры начального преобразования извлекаются из этого словаря.",
    "scale": 1.0,
    "rotation": [0.0 , 0.0, 0.0],
    "InitialTranslationOption": "GEOMETRY",
    "InitialTranslationOptionHelp":{
      "possible_options" : ["GEOMETRY", "MOMENTS", "MANUAL"]
    },
    "translation_info" : "Задействуется только если InitialTranslationOption = MANUAL.",
    "translation": [0, 0, 0]
  },
"imagej_landmark_coords_file_path_info" : ["Используется в режиме POINTS.",
                                           "У ImageJ есть плагин: plugins/registration/3d landmarks,",
                                           "позволяющий с помощью GUI для двух объемов создать текстовый файл,",
                                           "содержащий списки координат соответствующих точек в 2 объемах.",
                                           "Здесь указывается путь до файла такого типа, который автоматически парсится,",
                                           "и на основе этих координат производится начальное преобразование при совмещении"],
"imagej_landmark_coords_file_path" : "",

Первые два режима сразу встроены в SITK, другие интегрируются в его работу после некоторой обработки.

Рекомендации:

  • если ваши совмещаемые объемы слабо отличаются ориентацией (отличие не более 30 градусов), то лучше использовать MOMENTS;
  • режим GEOMETRY нельзя использовать, если объемы сильно отличаются ориентацией, например, если границы объекта в первом объеме в пределах 0-100 пикселей по одной из осей, а границы второго объема в пределах 500-600 пикселей, метод совместит центры изображений, но объекты в них могут не пересечься и метод даст некорректный результат, в целом лучше его никогда не использовать;
  • метод POINTS возможно один из лучших режимов на сложных данных, требует дополнительное ПО для разметки особых точек;
  • режим MATRIX удобен, если начальное преобразование ищется в таком ПО как, например, 3D Slicer - здесь есть возможность получить начальное преобразование сразу в виде матрицы.
Инициализация начального преобразования с помощью разметки особых точек (POINTS)

Начальное преобразование инициализируется на основе найденных соответствий между точками на двух изображениях. В качестве инструмента для разметки (разметчика) используется Fiji - расширенный дистрибутив ImageJ.

После запуска разметчика открывается основное окно image

До начала разметки необходимо загрузить объемы, между которыми производится поиск начального преобразования: File->Import->Image Sequence->Browse->Указать путь до папки с объемом->OK. В результате откроются два отдельных окна со срезами загруженных объемов image

Далее необходимо открыть окно разметчика: Plugins->Registration->Manual landmark selection (3d)->В открывшемся окне указать в качестве First image объем markup, Second image - moving->OK. После этого откроется окно, в котором будет содержаться информация о размеченных особых точках.

Разметка точек делается в окнах с загруженными объемами: двойным кликом необходимо выбрать какую-либо особую точку (угол объекта, граница и т.п.) на срезе первого объема, а затем эту же особую точку на срезе второго объема. Ограничений на количество точек нет, но чем больше их будет, тем точнее будет итоговое начальное преобразование. image

Информация о размеченных точка будет автоматически заноситься в соотвутстующее окно image

После того как разметка будет закончена необходимо сохранить файл с разметкой нажатием Save (этот файл не имеет формат, для просмотра можно использовать Notepad++). Для использования этого режима необходимо в файле конфига метода установить параметру InitialTransform значение POINTS, а также указать параметру imagej_landmark_coords_file_path в качестве значения путь до файла с разметкой.

Параметры SITK.

"InitialTransformViewer_info" : ["Если true, включает просмотр результата совмещения начальным",
                                 "преобразованием в режиме лоскутного наложения."],
"InitialTransformViewer" : false,


"Metric_info" : ["Тип используемой для итеративного совмещения метрики из набора метрик SITK",
                 "На данный момент реализована мультимодальная метрика совместной информации."],
"Metric" : "MattesMutualInformation",

"MMI_MetricNumberOfHistogramBins_info" : "Количество бинов в гистограмме для расчета метрики совместной информации.",
"MMI_MetricNumberOfHistogramBins" : 80,

"Interpolator_info" : "Тип интерполятора.",
"Interpolator" : "Linear",

"HistMatching_info" : ["True - выравнивание изображений по интенсивности с сохранением распределения",
                      "для корректной работы метрики совместной информации."],  
"HistMatching" : true,

"MetricSamplingStrategy_info" : ["Способ отбора вокселей для рассчета метрики.",
                                 "RegularGrid - равномерная сетка по всему объему;",
                                 "Random - в случайном порядке."],
"MetricSamplingStrategy" : "RegularGrid",

"Optimizer_info" : ["Тип оптимизатора из набора оптимизаторов в классе registration method из библиотеки SITK.",
                    "На текущий момент доступно два оптимизатора RegularStepGradientDescent и GradientDescent."], 
"Optimizer" : "RegularStepGradientDescent",

"Estimate_learning_rate_option_info" : ["Определяет, когда оптимизатор самостоятельно рассчитывает LearningRate:",
                   "Never - при оптимизации всегда используется заданный ниже размер шага оптимизации;",
                   "Once - размер шага рассчитывается автоматически один раз при переходе на новый уровень сжатия изображения;",
                   "EachIteration - величина шага рассчитывается на каждой итерации."],
"Estimate_learning_rate_option" : "Once",

"LearningRate_info" : "Величина шага оптимизатора.",
"LearningRate" : 2.0,

"NumberOfIterations_info" : "Ограничитель количества итераций на одном уровне сжатия изображения.",
"NumberOfIterations" : 150,

"minStep_info" : ["Только для оптимизатора RegularstepGradientDescent.",
                 "Останавливает оптимизацию на текущем уровне сжатия",
                 "при достижении указанного минимума для размера шага оптимизатора."],
"minStep" : 1e-5,

"relaxationFactor_info" : ["Только для оптимизатора RegularstepGradientDescent.",
                           "Величина, определяющая во сколько раз уменьшится шаг оптимизатора при смене направлении оптимизации",
                           "(это происходит при перескоке оптимизатора через минимум)."],
"relaxationFactor" : 0.7,

"gradientMagnitudeTolerance_info" : ["Только для оптимизатора RegularstepGradientDescent.",
                                     "Если на очередном шаге величина градиента меньше заданной,",
                                     "то на текущем уровне сжатия оптимизация останавливается."],
"gradientMagnitudeTolerance" : 1e-6,

"ConvergenceMinimumValue_info" : ["Только для оптимизатора GradientDescent.",
                                  "Если величина градиента меньше заданной на протяжении заданного числа шагов,",
                                  "то на текущем уровне сжатия оптимизация останавливается."],
"ConvergenceMinimumValue" : 1e-7,

"ConvergenceWindowSize_info" : ["Задает число шагов, на протяжении которых",
                                "градиент должен быть меньше заданного значения",
                                "для остановки оптимизации на текущем уровне сжатия изображения."],
"ConvergenceWindowSize" : 10,

"ShrinkFactors_info" : ["Задает уровни сжатия изображения,",
                        "на которых последовательно производится оптимизация.",
                        "Чаще всего производится сначала совмещение при большом сжатии в 4 раза,",
                        "потом при сжатии в 2 раза, потом в полном разрешении."],
"ShrinkFactors" : [4,2,1],

"SmoothingSigmas_info" : ["Задает гауссово размытие на указанный уровнях сжатия изображения",
                         "для большей гладкости оптимизируемой функции метрики."],
"SmoothingSigmas" : [2,1,0]

About

Toolkit for 3D volumetric data registration in common world coordinate system.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages