projects:otolaryngologist:task_calculate_volume

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revisionBoth sides next revision
projects:otolaryngologist:task_calculate_volume [2024/02/18 11:26] kelprojects:otolaryngologist:task_calculate_volume [2024/02/23 22:34] – Добавил ещё один способ выделения пазух; Добавил описание расчёта объёма прямо в Slicer 3D и их сравнения в виде таблиц psamsonov
Line 1: Line 1:
 ====== Расчёт объёма дыхательных пазух: выбор алгоритма/подхода ====== ====== Расчёт объёма дыхательных пазух: выбор алгоритма/подхода ======
  
-===== Способ через 3D =====+===== Способ через отдельную 3D-программу =====
 В качестве 3D программы для пробы того, что будет ли способ вообще рабочим, был выбран Blender, так как он поддерживает множество форматов, а также является open source приложением. В качестве 3D программы для пробы того, что будет ли способ вообще рабочим, был выбран Blender, так как он поддерживает множество форматов, а также является open source приложением.
  
-==== Что было попробовано: ==== +==== Преобразование nii в stl ====
- +
-=== Преобразование nii в stl ===+
 Было попробовано преобразование **nii** в **stl** через данный метод: \\ http://wiki.osll.ru/doku.php/projects:otolaryngologist:nii_to_mesh Было попробовано преобразование **nii** в **stl** через данный метод: \\ http://wiki.osll.ru/doku.php/projects:otolaryngologist:nii_to_mesh
  
-== Вывод: ==+=== Вывод: ===
 данная идея была сразу отброшена по данным причинам: данная идея была сразу отброшена по данным причинам:
     * Сложно настраивать параметры, потому что нужно каждый раз запускать скрипты, чтобы увидеть результат, так ещё и через двойной прогон; \\ \\ Без настройки параметров можно увидеть множество шумов и дефектов. \\  {{:projects:otolaryngologist:nii_to_stl.png?400|}} \\     * Сложно настраивать параметры, потому что нужно каждый раз запускать скрипты, чтобы увидеть результат, так ещё и через двойной прогон; \\ \\ Без настройки параметров можно увидеть множество шумов и дефектов. \\  {{:projects:otolaryngologist:nii_to_stl.png?400|}} \\
     * Также способ сам по себе не удобен и долгий, ведь предполагает использование множества шагов почти несвязанных друг с другом.     * Также способ сам по себе не удобен и долгий, ведь предполагает использование множества шагов почти несвязанных друг с другом.
  
-=== Анализ библиотеки плагинов 3D Slicer'а и его самого === +==== Анализ библиотек плагинов 3D Slicer'а для экспорта моделей ==== 
-    * Были найдены библиотеки для Python для импорта/экспорта разных 3D форматов из сохранённой сегментации, но это всё не равно не удобно, ведь присутствует дополнительный шаг, хоть и эта библиотека работает с уже сегментированном форматом файлов, поэтому позволяет подготовить сегментацию в 3D Slicer; \\ \\ Вот пример: \\ https://pypi.org/project/slicerio/+    * Были найдены библиотеки для Python для импорта/экспорта разных 3D форматов из сохранённой сегментации, но это всё не равно не удобно, ведь присутствует дополнительный шаг, хоть и эта библиотека работает с уже сегментированном форматом файлов, поэтому позволяет подготовить сегментацию в **3D Slicer**; \\ \\ Вот пример: \\ https://pypi.org/project/slicerio/
     * Также было найдено, что есть такой набор библиотек, как **VTK**. Он встроен в **3D Slicer**, что позволяет вообще нативно проводить сегментацию снимков (с множеством настроек), а также имеется так нужный нам экспорт.     * Также было найдено, что есть такой набор библиотек, как **VTK**. Он встроен в **3D Slicer**, что позволяет вообще нативно проводить сегментацию снимков (с множеством настроек), а также имеется так нужный нам экспорт.
  
-== Вывод: ==+=== Вывод: ===
 мы нашли способ позволяющий несколькими кликами экспортировать медицинские снимки в популярные 3D форматы файлов. мы нашли способ позволяющий несколькими кликами экспортировать медицинские снимки в популярные 3D форматы файлов.
  
-== Инструкция по способам: ==+=== Инструкция по способам: ===
 Давайте тут подробнее разберём шаги: Давайте тут подробнее разберём шаги:
     - Через **3D Slicer** открываем наши снимки (пусть для примера это будут **nii** файл);     - Через **3D Slicer** открываем наши снимки (пусть для примера это будут **nii** файл);
     - Далее нам нужно сегментировать нашу область, поэтому мы открываем **Segment Editor**, который находится в списке всех модулей по такому пути: **Segmentation/Segment Editor**;     - Далее нам нужно сегментировать нашу область, поэтому мы открываем **Segment Editor**, который находится в списке всех модулей по такому пути: **Segmentation/Segment Editor**;
-    - Создаём области с помощью инструмента **Threshold**. Выбираем в нём любой алгоритм; +    - Создаём области с помощью инструмента **Threshold**: крутим нижний порог до того, чтобы на взгляд почти везде хорошо выглядело;
-    - Крутим нижний порог до того, чтобы на взгляд почти везде хорошо выглядело;+
     - А на тех местах, где не дорисовывается стенка — мы используем инструмент **Paint** и дорисовываем;     - А на тех местах, где не дорисовывается стенка — мы используем инструмент **Paint** и дорисовываем;
-    - Затем мы переименовываем сегмент, как нам удобно и нажимаем на выдвигающиеся меню на кнопке с зелёной стрелкой. И выбираем пункт `Export to Files`. Выбираем разве что только путь, куда сохранится 3D объект и его формат (будем использовать `stl`); {{:projects:otolaryngologist:export_from_3d_slicer.png?400|}} +    - Затем мы переименовываем сегмент, как нам удобно и нажимаем на выдвигающиеся меню на кнопке с зелёной стрелкой. И выбираем пункт **Export to Files**. Выбираем разве что только путь, куда сохранится 3D объект и его формат (будем использовать **stl**); {{:projects:otolaryngologist:export_from_3d_slicer.png?400|}} 
-    - Уже в `Blenderудаляем внешние стенки (например через выделение через лассо с включенным `x-rayс видом сверху); +    - Уже в **Blender** удаляем внешние стенки (например через выделение через лассо с включенным **x-ray** с видом сверху); 
-    - Затем удаляем аккруратно всё лишнее посередине через тот же способ, что и выше; +    - Затем удаляем аккуратно всё лишнее посередине через тот же способ, что и выше; 
-    - Пользуемся функцией выделения сетки по соседям (Select Linked) на каждой из пазухи и делаем `Separateв отдельные объекты;+    - Пользуемся функцией выделения сетки по соседям (Select Linked) на каждой из пазухи и делаем **Separate** в отдельные объекты;
     - Подчищаем геометрию, если нужно. Можно даже подчистить с дырками;     - Подчищаем геометрию, если нужно. Можно даже подчистить с дырками;
-    - Ставим плагин под названием `Mesh: 3D-print Toolbox`+    - Ставим плагин под названием **Mesh: 3D-print Toolbox**
-    - Открываем в свойствах объекта вкладку `3D-printи пользуемся функцией `Clean Up/Make Manifold`, которая заделывает дырки; +    - Открываем в свойствах объекта вкладку **3D-print** и пользуемся функцией **Clean Up/Make Manifold**, которая заделывает дырки; 
-    - И нажимаем `Statistics/Volume- и видим объём. {{:projects:otolaryngologist:calculated_volume.png?400|}}+    - И нажимаем **Statistics/Volume** - и видим объём. {{:projects:otolaryngologist:calculated_volume.png?400|}}
   
-=== Проблемы и попытки их решить ===+==== Проблемы и попытки их решить ====
  
-== 3D объект получается большим == +=== 3D объект получается большим === 
-Из-за чего `Blender`'у немного тяжело работать в `Edit Mode(может в среднем думать по 2-3 секунды), когда мы пытаемся сделать какие-нибудь преобразования над мешем. +Из-за чего **Blender**'у немного тяжело работать в **Edit Mode** (может в среднем думать по 2-3 секунды на приблизительно среднем железе), когда мы пытаемся сделать какие-нибудь преобразования над мешем. 
-    * Можно уменьшить кол-во сетки с помощью модификатор `Decimateв Blender'е, но тогда мы можем потерять в точности вычисления объёма, поэтому мы отказались от такой идеи; +    * Можно уменьшить кол-во сетки с помощью модификатор **Decimate** в **Blender**'е, но тогда мы можем потерять в точности вычисления объёма, поэтому мы отказались от такой идеи; 
-    * Можно в `3D Slicer`'е воспользоваться инструментом `Scissors`, и он нам помогает, но уже в `Blenderпридётся аккуратнее тогда удалять стенки, которые появляются ещё в `3D Slicer`'е из-за логики работы сегментации. Ну и ножницами тоже надо аккуратнее пользоваться, чтобы не отрезать лишнего.+    * Можно в **3D Slicer**'е воспользоваться инструментом **Scissors**, и он нам помогает, но уже в **Blender** придётся аккуратнее тогда удалять стенки, которые появляются ещё в **3D Slicer**'е из-за логики работы сегментации. Ну и ножницами тоже надо аккуратнее пользоваться, чтобы не отрезать лишнего.
  
-== Невозможно подкрутить идеально Threshold в 3D Slicer'е. == +=== Невозможно подкрутить идеально Threshold в 3D Slicer'е. === 
-На выбор у нас есть множество алгоритмов: **Otsu**, **Huang**, **IsoData**, **Kittler-Illingworth**, **Maximum Entropy**, **Moments**, **Renyi entropy**, **Shanbhag**, **Triangle**, **Yen**. +На выбор у нас есть множество пресетов: **Otsu**, **Huang**, **IsoData**, **Kittler-Illingworth**, **Maximum Entropy**, **Moments**, **Renyi entropy**, **Shanbhag**, **Triangle**, **Yen**, но они все не работали хорошо на примере, который мы рассматривали и приходилось вручную двигать ползунки **threshold**'а.
  
-Мы попробовали их всех и пришли к таким выводам: +Но если даже двигать их вручную, то появлялись такие артефакты, как не бралась область, где на глаз должна быть стенка. Но когда мы увеличивали значение **threshold**'а, то брались области, где должна быть пустота.
-    - В целом визуально примерно все давали одинаковые результатыпоэтому сложно было выбрать какой-то конкретный; +
-    - Также во всех алгоритмах на некоторых снимках появлялись такие артефакты, как не бралась область, где на глаз должна быть стенка. Но когда мы увеличивали значение `threshold`'а, то брались области, где должна быть пустота.+
  
-Учитывая пункты выше было решено, что thresholdне надо завышать и легче воспользоваться инструментом `Paint` и провести стенки самим, там где они должны были быть. В основном это не надо делать больше, чем на нескольких снимках.+Учитывая пункты выше можно пойти двумя путями: 
 +    - **threshold** не надо завышать и нужно будет воспользоваться инструментом **Paint** и провести стенки самим, там где они должны были быть. В основном это не надо делать больше, чем на нескольких снимках; 
 +    - Либо же чуток завышаем **threshold**, чтобы появлялись артефакты, но мы ими просто пренебрегаем, потому что нам нужна приблизительная оценка. 
 + 
 +===== Только встроенными инструментами 3D Slicer'а ===== 
 + 
 +==== С использованием только лишь встроенного функционала ==== 
 +Был проанализирован функционал **3D Slicer**'а и были найдены такие интересные инструменты, как: 
 +    - Инструмент под названием **Islands** в модуле **Segment Editor**; 
 +    - Модуль **Segment Statistics**, который находится в категории **Quantification**. 
 + 
 +Сочетание этих двух инструментов открыл ещё более быстрый и удобный путь для получения объёма. 
 + 
 +=== Инструкция по нему === 
 +    - Первые шаги по открытии и выбора модуля **Segmentation/Segment Editor** аналогичны; 
 +    - Выбираем один из способов выделения областей описанных после данной инструкции и применяем его; 
 +    - Далее выбираем инструмент **Islands** и далее выбираем **Split Islands to segments**. В **Minumum Size** ставим, например, **70k** (данное значение позволило выделить только пазухи и оставляет всё ещё запас, потому что по итогу пазухи имели в районе **130k** вокселей, поэтому можно даже взять значение больше и не бояться, что пазухи не выделяться); 
 +    - Возможно перед следующим шагом надо будет применить ещё какие-то инструкции из способов ниже; 
 +    - Тут у нас должны остаться лишь 3 сегмента: две пазухи и внешняя часть. Если это не так, то можем повысить кол-во вокселей на прошлом шаге или вручную удалить, ведь внешнюю часть в любом случае надо будет удалить; 
 +    - Затем заходим в **Quantification/Segment Statistics** и выбираем в поле **Segmentation** нашу сегментацию с двумя сегментами (то есть нашими пазухами); 
 +    - В `Advanced` по умолчанию настроено ужекак нам нужно, но можно на всякий случай убрать **Scalar Volume**, потому что там будут идентичные результаты с **Label Map** (хотя он и так работает только тогда, когда выбираешь **Scalar Volume** вместо **None**, поэтому и говорю, что и по умолчанию всё хорошо);<WRAP center round important> 
 +Не знаю почему, но **Closed Surface** работает только тогда, когда в **Segment Editor** включено **Show 3D**. 
 +</WRAP> 
 +    - Нажимаем **Apply** и видим результаты. Их разбор будет пунктом ниже. 
 + 
 +=== Алгоритмы выбора сегментов === 
 +    - Вручную дополнять: \\ <WRAP> 
 +Это случай с завышением **Threshold**'а и ручным дорисовыванием с помощью инструмента **Paint** или убирать лишнее с помощью **Erase**. 
 + 
 +**Результаты:** 
 +| Segment | Voxel count | Volume mm3 (LM) | Volume cm3 (LM) | Surface mm2 | Volume mm3 (CS) | Volume cm3 (CS) | 
 +| Left    | 152976      | 19122           | 19.122          | 4232.45     | 19179           | 19.179          | 
 +| Right   | 136020      | 17002.5         | 17.0025         | 4071.59     | 17056.4         | 17.0564         | 
 +**Вывод:** Это не удобно и очень муторно. 
 +</WRAP> 
 +    - Завысить Threshold: \\ <WRAP> 
 +Главное, чтобы пазуха была отдельной частью. 
 + 
 +**Результаты:** 
 +| Segment | Voxel count | Volume mm3 (LM) | Volume cm3 (LM) | Surface mm2 | Volume mm3 (CS) | Volume cm3 (CS) | 
 +| Left    | 121637      | 15204.6         | 15.2046         | 4759.2      | 15287.7         | 15.2877         | 
 +| Right   | 118842      | 14855.2         | 14.8552         | 4451.78     | 14916.7         | 14.9167         | 
 +**Вывод:** имеет смысл, но результаты получаются не такими точными и красивыми, как хотелось бы. 
 +</WRAP> 
 +    - Завысить Threshold c Smoothing \\ <WRAP> 
 +Инструкция: 
 +        - после применения инструмента **Islands** мы для **каждой** из пазух применяем инструмент **Smoothing** в режиме **Closing (fill holes)** (я выбрал **10.00mm**); 
 + 
 +**Результаты:** 
 +| Segment | Voxel count | Volume mm3 (LM) | Volume cm3 (LM) | Surface mm2 | Volume mm3 (CS) | Volume cm3 (CS) | 
 +| Left    | 135528      | 16941           | 16.941          | 3913.61     | 16994           | 16.994          | 
 +| Right   | 132024      | 16503           | 16.503          | 3928.04     | 16556.9         | 16.5569         | 
 +**Вывод:** уже в разы лучше. 
 +</WRAP> 
 +    - С использованием Margin и опционально Smoothing \\ <WRAP> 
 +Инструкция: 
 +        - Тут мы можем взять такой **Threshold**, который будет удовлетворять визуально и забить на то, что могут быть небольшие соединения пазух с другими элементами носа. И применяем его; 
 +        - Затем мы выбираем инструмент **Margin** и выбираем в **Operation**: **Shrink**а в качестве размера можно выбрать: **1.00mm**; 
 +        - Далее используем инструмент **Islands** по инструкции выше; 
 +        - И теперь применяем обратно **Margin** с таким же размером, но в режиме: **Grow**. 
 +        - Опционально ещё можем применить инструмент **Smoothing** в режиме **Closing (fill holes)**, например, на **5.00mm**. 
 + 
 +**Результаты только с Margin:** 
 +| Segment | Voxel count | Volume mm3 (LM) | Volume cm3 (LM) | Surface mm2 | Volume mm3 (CS) | Volume cm3 (CS) | 
 +| Left    | 145906      | 18238.2         | 18.2383         | 4250.16     | 18284.2         | 18.2842         | 
 +| Right   | 141524      | 17690.5         | 17.6905         | 4202.23     | 17743           | 17.743          | 
 + 
 +**Результаты также ещё и с Closing (fill holes) (5.00mm):** 
 +| Segment | Voxel count | Volume mm3 (LM) | Volume cm3 (LM) | Surface mm2 | Volume mm3 (CS) | Volume cm3 (CS) | 
 +| Left    | 148392      | 18549           | 18.549          | 4114.5      | 18608.2         | 18.6082         | 
 +| Right   | 143420      | 17927.5         | 17.9275         | 4130.2      | 17986.9         | 17.9869         | 
 + 
 +**Выводы:** 
 +По результатам можно увидеть, что **Smoothing** (остальные алгоритмы я тоже пробовал, но они визуально работали хуже) не особо что-то меняет, потому что и без него получается очень приближённо к настоящим результатам, но при этом он бывает сглаживает не в тех местах, из-за чего, например, **Right** и повысился. Поэтому данный способ лучше юзать без сглаживания (либо с небольшим сглаживанием, но результаты тогда будут на уровне +1-2%). 
 +</WRAP> 
 + 
 +=== Выводы === 
 +Лучше всего показал себя последний способ с использованием **Margin** и без **Smoothing**. И если я правильно вручную выбрал пазухи, то отставание получается в примерно 5%.
  
-  
 ===== На чём остановились ===== ===== На чём остановились =====
projects/otolaryngologist/task_calculate_volume.txt · Last modified: 2024/05/06 20:48 by psamsonov