3D Graphics/VTK

vtkImageData 구조

leonhong 2022. 6. 12. 15:10

개요

 이미지 데이터는 사진이나 CT등과 같은 데이터를 말하는데, VTK에서는 이것들을 vtkImagedata로 처리합니다.

 

일반적인 그림파일을 표현하는 방법

  누군가가 그림판위에  8(pixel) x 8(pixel) 짜리 작은 컬러 아이콘을 그렸다고 가정해 보겠습니다. 

  이 그림을 나타내는 속성은 아래와 같습니다.

      - Pixel type : Byte타입의 RGB

      - Size : 8 x 8

  컴퓨터의 이미지는 우리가 눈에 보이는 컬러는 RGB색상인데, Alpha라는 투명도를 이용하기도 합니다. 그래서 통상적으로 하나의 Pixel은 RGB 3개의 속성이 존재하고 각 속성은 0~255의 범위로 나타내기 때문에 Byte(8bit)타입으로 사용합니다. 그리하여 전체 데이터의 크기는 8 x 8 x 3Byte 가 됩니다. 

 

VTK에서 그림파일(Image Data)를 표현하는 방법

 vtk에서는 좌표의 개념이 중요하기 때문에 "일반적인 그림파일의 표현"하는 것에 좌표를 처리하는 개념이 추가되어 있습니다. 

 8(pixel) x 8(pixel) 짜리 작은 컬러 아이콘을 vtkImagedata에서 표현하는 속성은 아래와 같습니다.(Pixel과 Voxel은 동일한개념인데, 2D와 3D에서 구분하여 명명을 하는것이므로 동일하다고 보시면 됩니다.)

      Voxel 하나의 속성

      - Scalar Component Count :  하나의 voxel이 몇개의 속성을 가지고 있는가? (여기서는 RGB 3개. 참고로 DICOM파일은 보통 1개)

      - Scalar Type : RGB의 개별 구성요소의 타입. ( 여기서는 Byte. 참고로 DICOM파일은 보통 Short타입)

      - Scalar Size(Byte) : RGB의 개별 구성요소의 크기가 얼마인가? (여기서는 Byte이므로 1. 참고로 Short 타입은 2Byte 이므로 2)

 

      좌표계 관련된 속성

      - Origin : 이미지의 원점(시작)좌표(여기서는 0,0,0)

      - Spacing : Voxel과 Voxel사이의 간격(Voxel 하나의 크기로 봐도 무방함. 여기서는 1.0)

      - Dimension : X, Y, Z 축별 Voxel의 개수(여기에서는 8,8,1)

      - Extent : X, Y, Z 축별 데이터 배열의 최소, 최대 인덱스로써 [xMin, xMax, yMin, yMax, zMin, zMax]의 형태로 표현(여기서는 0,7,0,7,0,0)

     ps. Origin과 Spacing과 Dimension을 알면 현재 이미지 데이터의 끝부분 위치를 알수 있게 됩니다. 

 

VTK Image Data 표현이 복잡한 이유

 VTK는 과학과 의료분야에서 널리 사용되는 라이브러리인데, 이곳에서 출력되는 데이터들(예를 들어 DICOM)은 현실에서 사용하는 공간의 개념이 들어가 있기 때문에, 실제 사용되는 거리계산법(예를 들어 미터법)을 적용하여 데이터를 표현해줘야 하므로 사진 데이터를 처리하는 bmp, jpg, png등과 같은 데이터보다는 복잡할수밖에 없습니다. 예를 들어 얼굴 CT 데이터를 보면 앞니간의 간격을 mm 단위로 알수 있지만, 사진을 보고는 알수 없습니다.

 

VTK Image Data를 Python으로 다뤄보기

 Python을 이용하여 이미지 속성을 출력해보고, 색상값을 변경해보는 코드를 작성해 보겠습니다.

 

from vtkmodules.all import vtkPNGReader, vtkPNGWriter, vtkImageData

# 100 x 100 흰색 RGB타입의 png 이미지 파일 로드
reader = vtkPNGReader()
reader.SetFileName("white100.png")
reader.Update()

# 로드된 image data 가져오기
imageData: vtkImageData = reader.GetOutput()

# image data scalar 속성 확인
print('Scalar type : ', imageData.GetScalarTypeAsString())
print('Scalar size : ', imageData.GetScalarSize())
print('Scalar Component count : ', imageData.GetNumberOfScalarComponents())

# image data 공간 속성 확인
print('Origin : ', imageData.GetOrigin())
print('Spacing : ', imageData.GetSpacing())
print('Dimension : ', imageData.GetDimensions())
print('Extent : ', imageData.GetExtent())

# # 10, 10, 0의 위치에 RGB값 알아오기
print('(10, 10, 0) R : ', imageData.GetScalarComponentAsFloat(10, 10, 0, 0)) # R
print('(10, 10, 0) G : ', imageData.GetScalarComponentAsFloat(10, 10, 0, 1)) # G
print('(10, 10, 0) B : ', imageData.GetScalarComponentAsFloat(10, 10, 0, 2)) # B

# 10, 10, 0의 위치에 RGB(255, 0, 0)짜리 점찍기(붉은색)
imageData.SetScalarComponentFromFloat(10, 10, 0, 0, 255) # R
imageData.SetScalarComponentFromFloat(10, 10, 0, 1, 0) # G
imageData.SetScalarComponentFromFloat(10, 10, 0, 2, 0) # B

# 변경된 이미지 출력
writer = vtkPNGWriter()
writer.SetFileName('after.png')
writer.SetInputData(imageData)
writer.Write()

'3D Graphics > VTK' 카테고리의 다른 글

대용량 image 파일 서버 전송(예정)  (0) 2022.06.15
web에서 DICOM 파일 로드하기  (0) 2022.06.02
Python 개발 환경 설정  (0) 2022.03.28