- 이 부분에 대한 소스 코드는 다음 파일에서 찾을 수 있다
- Examples/DataRepresentation/Image/Image5.cxx
- 이 예제는 itk::Image 클래스에서 데이터를 가져오는 방법을 보여준다
- 이것은 특별히 다른 소프트웨어 시스템과 인터페이스 하는데에 유용하다
- 많은 시스템은 이미지 픽셀 데이터에 대해 버퍼로 메모리의 인접한 블럭을 사용한다
- 현재의 예제는 이 경우라고 가정하고 버퍼를 itk::ImportImageFilter로 제공한다. 그렇게 함으로써 결과물로 이미지를 생성한다
- 재미를 위해 우리는 지역적으로 할당된 버퍼에서 중심에 구를 가진 합성 이미지를 생성하고 메모리의 이 블럭에 ImportImageFilter로 통과한다
- 이 예제는 실행을 위해 설정하고, 사용자는 명령어 라인 파라미터로 출력 파일의 이름을 제공해야 한다
- 첫째로, ImportImageFilter 클래스의 헤더 파일을 포함해야 한다
#include "itkImage.h"
#include "itkImportImageFilter.h"
- 다음에, 우리는 이미지 픽셀을 나타내기 위해 사용하는 데이터 타입을 선택한다
- 우리는 메모리의 외부 블럭이 픽셀을 나타내기 위해 같은 데이터 타입을 사용한다고 가정한다
typedef unsigned char PixelType;
const unsigned int Dimension = 3;
typedef itk::Image< PixelType, Dimension > ImageType;
- ImportImageFilter의 타입은 다음 줄에서 인스턴스화된다
typedef itk::ImportImageFilter< PixelType, Dimension > ImportFilterType;
- 그리고 나서 New() 메서드를 사용하여 생성된 필터 객체는 SmartPointer에 할당된다
ImportFilterType::Pointer importFilter = ImportFilterType::New();
- 이 필터는 사용자가 결과물로 생성된 이미지의 크기를 지정하는 것을 요구한다
- SetRegion() 메서드는 이 끝에 사용된다
- 이미지 크기는 정확히 지역적으로 할당된 버퍼 안에 사용 가능한 픽셀의 수와 매칭되어야 한다
ImportFilterType::SizeType size;
size[0] = 200;
size[1] = 200;
size[2] = 200;
ImportFilterType::IndexType start;
start.Fill( 0 );
ImportFilterType::RegionType region;
region.SetIndex( start );
region.SetSize( size );
importFilter->SetRegion( region );
- 결과 이미지의 원점은 SetOrigion() 메서드를 가지고 지정한다
double origin[ Dimension ];
origin[0] = 0.0;
origin[1] = 0.0;
origin[2] = 0.0;
importFilter->SetOrigin( origin );
- 이미지의 공간은 SetSpacing() 메서드를 가지고 통과된다
double spacing[ Dimension ];
spacing[0] = 1.0;
spacing[1] = 1.0;
spacing[2] = 1.0;
importFilter->SetSpacing( spacing );
- 다음에 우리는 ImportImageFilter에 전달하기 위한 픽셀 데이터를 포함하는 메모리 블럭을 할당한다
- 우리는 SetRegion() 메서드를 가지고 지정된 같은 크기를 정확히 사용한다는 것을 주목하라
- 실제 응용 프로그램에서 이미지를 나타내기 위해 다른 데이터 구조를 사용하여 일부 다른 라이브러리로부터 이 버퍼를 얻을 수 있다
const unsigned int numberOfPixels = size[0] * size[1] * size[2];
PixelType* localBuffer = new PixelType [ numberOfPixels ];
- 여기에서 우리는 바이너리 구로 버퍼를 채울 것이다
- ITK는 픽셀에 접근하기 위해 내부 코드 내에서 for 루프를 사용하지 않는 다는 것을 주목하라
- 모든 픽셀 접근 방법은 n 차원 이미지의 관리를 지원하는 itk::ImageIterator를 사용하여 대신 수행된다
const double radius2 = radius * radius;
PixelType * it = localBuffer;
for(unsigned int z=0; z < size[2]; z++)
{
const double dz = static_cast<double>( z ) - static_cast<double>(size[2])/2.0;
for(unsigned int y=0; y < size[1]; y++)
{
const double dy = static_cast<double>( y ) - static_cast<double>(size[1])/2.0;
for(unsigned int x=0; x < size[0]; x++)
{
const double dx = static_cast<double>( x ) - static_cast<double>(size[0])/2.0;
const double d2 = dx*dx + dy*dy + dz*dz;
*it++ = ( d2 < radius2 ) ? 255 : 0;
}
}
}
- 그 버퍼는 SetImportPointer()를 가지고 ImportImageFilter에 전달된다
- 메모리 블럭을 적절하게 삭제하기 위해, 메모리는 C++ new() 연산자를 가지고 할당된 메모리여야 한다
- C malloc 또는 calloc 과 같은, 다른 메모리 할당 메커니즘을 가지고 할당된 메모리는 ImportImageFilter는 적절히 삭제될 수 업스을 것이다
- 다르게 말하면, C++ new 연산자로 할당된 메모리를 삭제하기 위한 ImportImageFilter가 오직 허가가 주어지는 것은 오직 응용 프로그램 프로그래머의 책임이다
const bool importImageFilterWillOwnTheBuffer = true;
importFilter->SetImportPointer(localBuffer, numberOfPixels, importImageFilterWillOwnTheBuffer);
- 마지막으로 우리는 파이프라인에 이 필터의 결과물을 연결할 수 있다
- 간단한 것을 위해 우리는 단지 여기에서 writer를 사용한다
- 그러나 그것은 어떤 다른 필터도 될 수 있다
writer->SetInput( importFilter->GetOutput() );
- 우리는 버퍼에 delete 를 호출하지 않는 것에 주목하라. 왜냐하면 SetImportPointer() 의 마지막 전달인자로 true를 넣기 때문이다
- 지금 그 버퍼는 ImportImageFilter에 의해 소유된다
댓글