CT 데이터는 3D 픽셀(=Voxel)로 이루어져 있으며, 각 Voxel에는Hounsfield Unit (HU) 값이 있습니다.
Hounsfield Unit 이란?
HU는 물질이 X-ray를 얼마나 흡수하느냐(=조직의 밀도)를 숫자로 나타낸 값입니다.
주로 사람의 몸에 대한 X-ray 영상을 취득할 때, 각 조직(tissue)의 밀도(density)를 표현하는 단위로 사용됩니다.
X-ray가 많이 흡수될수록 (즉, density가 높을수록) HU값이 크고, 적게 흡수될수록 (즉, density가 낮을수록) HU값이 작습니다.
조직 | HU | |
공기 | Air | 약 -1000 HU |
폐 영역 | Lung area | 약 -500 HU |
지방 조직 | Fats | 약 -100 ~ -50 HU |
물 | Water | 0 HU |
근육 | Muscle | 약 50 ~ 100 HU |
뼈(해면골) | Cancellous bone | 약 150 ~ 300 HU |
뼈(치면골) | Compact bone | 약 700 ~ 3000 HU |
위 값을 사용하였을 때, 뼈 영역을 추출하기 위해서는 약 200 HU 이상을 선택하면 됩니다.
dicom 데이터(CT image)에서 뼈 영역만 남기기
vtkFlyingEdges3D 알고리즘은 3D 스칼라 필드에서 등표면(isosurface) 을 추출하는 알고리즘입니다.
vtkMarchingCubes 보다 빠른 고속 등표면 추출 알고리즘으로, 본 예제에서는 vtkFlyingEdges3D 알고리즘을 사용하겠습니다.
우선 vtkDICOMImageReader를 사용하여 dicom 이미지를 불러와 줍니다.
vtkSmartPointer<vtkActor> CvtkMFCDlgEXDlg::initImageActor(CString cstrImagePath)
// cstrImagePath: .dcm이 들어있는 폴더 directory
{
vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New();
const char* charPath = (char*)(LPCTSTR)cstrImagePath;
reader->SetDirectoryName(charPath);
reader->Update();
dicom 이미지를 불러온 후, 해당 3d 볼륨데이터를 가져와서 vtkFlyingEdges3D 에 입력으로 연결합니다.
vtkNew<vtkFlyingEdges3D> flyingEdges3D_bone;
flyingEdges3D_bone->SetInputConnection(reader->GetOutputPort());
flyingEdges3D_bone->SetValue(0, 250);
vtkNew<vtkPolyDataMapper> mapper_bone;
mapper_bone->SetInputConnection(flyingEdges3D_bone->GetOutputPort());
mapper_bone->ScalarVisibilityOff(); //스칼라 값을 무시하고, 지정한 색상이나 재질을 그대로 사용하기 위해
vtkNew<vtkActor> actor;
actor->SetMapper(mapper_skin);
actor->GetProperty()->SetDiffuseColor(colors->GetColor3d("BoneColor").GetData()); // 뼈색상(흰색)으로 객체 설정
actor->GetProperty()->SetSpecular(0.3); // 광택 반사계수 (0.0: 매트, 1.0: 매우 강한 광택)
actor->GetProperty()->SetSpecularPower(20); //광택 집중도 설정 (1~5: 광택 넓고 퍼짐, 플라스틱 같이, 10~100: 광택 좁고 선명, 금속 같이)
return actor;
}
- SetValue(index, value)는 특정 등치값(iso-value) 에 해당하는 표면을 추출하겠다는 뜻입니다.
- 여기서 index = 0은 첫 번째 등표면 설정이라는 뜻이고,
- value = 250은 HU(Hounsfield Unit) 기준으로 200이라는 밀도를 가진 등표면을 생성하겠다는 의미입니다.
쉽게 말하면: 👉 "HU 값이 250인 영역에서 등표면을 만들어줘! (예: 뼈의 시작 부분)"
이렇게 진행하면 다음과 같은 결과를 얻을 수 있습니다.
그런데 그림을 보시면 뼈 영역 뿐만 아니라 지저분한 배경 이 같이 나온 것을 확인할 수 있습니다.
이것은 뼈영역 분할을 위해, 단지 밀도의 범위 (사실 따지고 보면 색상 영역)으로만 분할을 진행하였기 때문에
뼈 영역과 비슷한 밀도값을 가지게 되면 모두 분할되기 때문입니다.
그렇다면 여기서 뼈만 예쁘게 뽑고 싶다면 어떻게 하면 될까요 ??
TO BE CONTINUE 😏
'Programming > VTK' 카테고리의 다른 글
[VTK] 3d 데이터에서 가장 큰 영역만 추출하기 (MFC, vs2019) (0) | 2025.03.21 |
---|---|
[VTK] 조명 설정하기 (vtkLight)(MFC, vs2019) (0) | 2025.03.20 |
[VTK] screen 좌표를 vtk world 좌표로 변환하기 (1) | 2024.04.16 |
[VTK] VTK에서 원 그리기 (C++, MFC) (0) | 2024.04.05 |