1、使用 vtkImageMask 实现。
优点:简单方便,mask与原始图像大小一致;
缺点:只支持单一掩码图像,无法实现多个掩码的编辑;
2、演示源码
void ImageMask2()
{
// 读取数据
int m_Dim[3] = { 512,512,333 };
double m_Spacing[3] = { 0.32,0.32,0.8 };
double m_Origin[3];
m_Origin[0] = -m_Dim[0] * m_Spacing[0] * 0.5;
m_Origin[1] = -m_Dim[1] * m_Spacing[1] * 0.5;
m_Origin[2] = -m_Dim[2] * m_Spacing[2] * 0.5;
size_t fSize = m_Dim[0] * m_Dim[1] * m_Dim[2] * sizeof(short);
vtkImageData* input = vtkImageData::New();
input->SetDimensions(m_Dim[0], m_Dim[1], m_Dim[2]);
input->SetSpacing(m_Spacing[0], m_Spacing[1], m_Spacing[2]);
input->SetOrigin(m_Origin);
input->AllocateScalars(VTK_SHORT, 1);
void *ptr = input->GetScalarPointer();
//memcpy(ptr, m_pSrcData->m_pSrc, fSize);
std::string m_ImgFile = "D:\\spineCT\\IMG-0001-00001.img";
FILE *pFile = fopen(m_ImgFile.c_str(), "rb");
if (pFile == NULL)
return;
fread(ptr, 1, fSize, pFile);
fclose(pFile);
//====================================================
// 创建测试掩码图像
vtkImageData* mask = vtkImageData::New();
mask->SetDimensions(m_Dim[0], m_Dim[1], m_Dim[2]);
mask->SetSpacing(m_Spacing[0], m_Spacing[1], m_Spacing[2]);
mask->SetOrigin(m_Origin);
mask->AllocateScalars(VTK_UNSIGNED_CHAR, 1);
void *ptrMak = mask->GetScalarPointer();
memset(ptrMak, 0, 512 * 512 * 333);
unsigned char* pMask = (unsigned char*)ptrMak;
for (int i = 0; i < 333; i++)
{
for (int j = 200; j < 400; j++)
{
for (int k = 200; k < 400; k++)
{
pMask[i * 512 * 512 + j * 512 + k] = 255;
}
}
}
//====================================================
vtkSmartPointer<vtkImageMapToWindowLevelColors> windowLevel = vtkSmartPointer<vtkImageMapToWindowLevelColors>::New();
windowLevel->SetWindow(800);
windowLevel->SetLevel(800);
windowLevel->SetInputData(input);
windowLevel->Update();
vtkNew<vtkImageMask> maskFilter;
maskFilter->SetImageInputData(windowLevel->GetOutput());
maskFilter->SetMaskInputData(mask);
maskFilter->SetMaskedOutputValue(255, 0, 0);
maskFilter->SetMaskAlpha(0.4);
maskFilter->NotMaskOn(); // 255 不可见
maskFilter->Update();
int imeExtent[6];
input->GetExtent(imeExtent);
input->GetExtent(ImageExtent);
imeExtent[4] = 0;
imeExtent[5] = 0;
// Display the image
vtkSmartPointer<vtkImageActor> actor = vtkSmartPointer<vtkImageActor>::New();
actor->GetMapper()->SetInputConnection(maskFilter->GetOutputPort());
actor->SetDisplayExtent(imeExtent);
//itemActor->SetOrigin();
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
vtkCamera* camera = renderer->GetActiveCamera();
camera->ParallelProjectionOn();
camera->SetParallelScale(100);
camera->SetFocalPoint(0,0,0);
camera->SetPosition(0,0,400);
camera->SetViewUp(0,1,0);
vtkSmartPointer<vtkRenderWindow> window = vtkSmartPointer<vtkRenderWindow>::New();
window->AddRenderer(renderer);
// Set up the interaction
vtkSmartPointer<vtkInteractorStyleImage> imageStyle = vtkSmartPointer<vtkInteractorStyleImage>::New();
vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor->SetInteractorStyle(imageStyle);
window->SetInteractor(interactor);
window->Render();
vtkSmartPointer<vtkImageInteractionCallback> callback = vtkSmartPointer<vtkImageInteractionCallback>::New();
callback->SetImageReslice(actor, itemActor, renderer);
callback->SetInteractor(interactor);
imageStyle->AddObserver(vtkCommand::MouseMoveEvent, callback);
imageStyle->AddObserver(vtkCommand::LeftButtonPressEvent, callback);
imageStyle->AddObserver(vtkCommand::LeftButtonReleaseEvent, callback);
imageStyle->AddObserver(vtkCommand::KeyPressEvent, callback);
// Start interaction
// The Start() method doesn't return until the window is closed by the user
interactor->Start();
}
3、勾画交互-矩形工具
4、勾画交互-圆形工具