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 revision
Previous revision
Last revisionBoth sides next revision
projects:otolaryngologist:task_calculate_volume [2024/02/18 11:26] kelprojects:otolaryngologist:task_calculate_volume [2024/02/23 22:37] – Поправил расположение скриншота 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