Python

ITK 使用 BinaryMask3DMeshSource 將二元影像轉為 Surface 教學與範例

介紹如何使用 ITK 的 BinaryMask3DMeshSource 將二元影像(binary image)轉為網格(mesh)構成的 surface。

Python 語言版本

BinaryMask3DMeshSource 可以將三維的二元遮罩影像轉換為網格,首先定義好來源遮罩影像的類型,以及轉出的網格類型:

import itk
import matplotlib.pyplot as plt

# 設定網格與影像的類型
MeshType = itk.Mesh[itk.F, 3]
PixelType = itk.UC
ImageType = itk.Image[PixelType, 3]

讀取二元遮罩影像(這裡使用 Allen Mouse Brain CCFv3 標註影像作為範例):

# 讀取二元遮罩影像
maskImageFilename = "structure_477.nrrd"
maskImage = itk.imread(maskImageFilename, PixelType)

先以 matplotlib 查看遮罩影像各方向的截面:

# 查看遮罩影像各方向截面
nda = itk.GetArrayViewFromImage(maskImage)
fig, axs = plt.subplots(1, 3, figsize=(15, 5))
axs[0].imshow(nda[nda.shape[0]//2,:,:], cmap = 'gray')
axs[1].imshow(nda[:,nda.shape[1]//2,:], cmap = 'gray')
axs[2].imshow(nda[:,:,nda.shape[2]//2], cmap = 'gray')
plt.show()
遮罩影像各方向截面

建立 BinaryMask3DMeshSource 之後,設定來源影像與物件的遮罩數值,即可將遮罩轉為網格:

# 以 BinaryMask3DMeshSource 將遮罩影像轉為網格
MeshSourceType = itk.BinaryMask3DMeshSource[ImageType, MeshType]
meshSource = MeshSourceType.New()
meshSource.SetInput(maskImage)
meshSource.SetObjectValue(1)
meshSource.Update()

# 取得產生的網格結果
mesh = meshSource.GetOutput()

itkwidgets 顯示網格:

# 以 itkwidgets 顯示網格
import itkwidgets
itkwidgets.view(geometries = mesh)
網格資料

若要將產生的網格資料儲存起來,可以使用 MeshFileWriter

# 儲存 Mesh 網格檔案
meshWriter = itk.MeshFileWriter[MeshType].New()
meshIO = itk.OBJMeshIO.New()
meshWriter.SetMeshIO(meshIO)
meshWriter.SetInput(mesh)
meshWriter.SetFileName("mesh.obj")
meshWriter.Update()

C++ 語言版本

在 C++ 中使用 BinaryMask3DMeshSource 的方式也都相同,只是以不同程式語言實作而已。

#include <itkImageFileReader.h>
#include <itkBinaryMask3DMeshSource.h>
#include <itkMeshFileWriter.h>
#include <itkOBJMeshIO.h>
#include <itkImage.h>

int main() {
  // 設定網格與影像的類型
  using MeshType = itk::Mesh<double, 3>;
  using PixelType = unsigned char;
  using ImageType = itk::Image<PixelType, 3>;

  // 讀取二元遮罩影像
  using ReaderType = itk::ImageFileReader<ImageType>;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName("structure_477.nrrd");

  // 以 BinaryMask3DMeshSource 將遮罩影像轉為網格
  using MeshSourceType = itk::BinaryMask3DMeshSource<ImageType, MeshType>;
  MeshSourceType::Pointer meshSource = MeshSourceType::New();
  meshSource->SetInput(reader->GetOutput());
  meshSource->SetObjectValue(1);
  meshSource->Update();

  // 儲存 Mesh 網格檔案
  using MeshWriterType = itk::MeshFileWriter<MeshType>;
  MeshWriterType::Pointer meshWriter = MeshWriterType::New();
  meshWriter->SetMeshIO(itk::OBJMeshIO::New());
  meshWriter->SetInput(meshSource->GetOutput());
  meshWriter->SetFileName("mesh.obj");
  meshWriter->Update();

  return EXIT_SUCCESS;
}

將此 C++ 範例程式碼儲存於 ConvImage2Mesh.cpp 之後,搭配以下 CMakeLists.txt 設定以 CMake 編譯:

cmake_minimum_required(VERSION 3.10.2)

# 設定專案名稱
project(ConvImage2Mesh)

# 尋找並引入 ITK 函式庫
find_package(ITK REQUIRED)
include(${ITK_USE_FILE})

# 增加一個執行檔
add_executable(ConvImage2Mesh ConvImage2Mesh.cpp)

# 定義執行檔連結方式
target_link_libraries(ConvImage2Mesh ${ITK_LIBRARIES})

參考資料:SurfaceExtraction.cxxVTK MarchingCubes ExampleMedical1.pyvtkContourFilter ExamplesVTK ExtractSurface Example

Share
Published by
Office Guide
Tags: ITK

Recent Posts

Python 使用 PyAutoGUI 自動操作滑鼠與鍵盤

本篇介紹如何在 Python ...

1 年 ago

Ubuntu Linux 以 WireGuard 架設 VPN 伺服器教學與範例

本篇介紹如何在 Ubuntu ...

1 年 ago

Linux 網路設定 ip 指令用法教學與範例

本篇介紹如何在 Linux 系...

1 年 ago

Linux 以 Cryptsetup、LUKS 加密 USB 隨身碟教學與範例

介紹如何在 Linux 系統中...

1 年 ago