通过LabelGeometryImageFilter可以求Label Image各个区域的质心和BoundingBox。然而,如果图像的spacing不是1,它并不会考虑进去,因此得到的结果并未我们所愿的。针对这个问题,有人实现了相关的模块(itkOBBLabelMap),可以解决这个问题,将其添加到源码,然后重新配置和编译即可。
1 QList <QPoint3D> calculateRegionCentroid(vtkImageData *data)
2 {
3 QList < QPoint3D > centroids; // QPoint3D是仿照QPoint(不支持浮点数)而定义的一个类,支持浮点数
4
5 if ( !data )
6 return centroids;
7
8 double spacing[3];
9 data->GetSpacing( spacing );
10
11 itk::VTKImageToImageFilter<UCharImageType>::Pointer vtk2itkConnector // 将VTK图像转换为ITK图像
12 = itk::VTKImageToImageFilter< UCharImageType>::New();
13
14 BinaryImageToLabelMapFilterType::Pointer binaryImageToLabelMapFilter
15 = BinaryImageToLabelMapFilterType::New();
16
17 LabelMapToLabelImageFilterType::Pointer labelMapToLabelImageFilter
18 = LabelMapToLabelImageFilterType::New();
19
20 LabelGeometryImageFilterType::Pointer labelGeometryImageFilter
21 = LabelGeometryImageFilterType::New();
22
23 vtk2itkConnector->SetInput( data );
24
25 binaryImageToLabelMapFilter->SetInput( vtk2itkConnector->GetOutput() );
26
27 labelMapToLabelImageFilter->SetInput( binaryImageToLabelMapFilter->GetOutput());
28
29 labelGeometryImageFilter->SetInput( labelMapToLabelImageFilter->GetOutput() );
30
31 // These generate optional outputs.
32 labelGeometryImageFilter->CalculatePixelIndicesOn();
33 labelGeometryImageFilter->CalculateOrientedBoundingBoxOn();
34 labelGeometryImageFilter->CalculateOrientedLabelRegionsOn();
35 labelGeometryImageFilter->Update();
36
37 LabelGeometryImageFilterType::LabelsType allLabels = labelGeometryImageFilter->GetLabels();
38 LabelGeometryImageFilterType::LabelsType::iterator allLabelsIt;
39
40 for( allLabelsIt = allLabels.begin(); allLabelsIt != allLabels.end(); allLabelsIt++ ) {
41 LabelGeometryImageFilterType::LabelPixelType labelValue = *allLabelsIt;
42 if ( (int)labelValue > 0 ) {
43 double x = labelGeometryImageFilter->GetCentroid( labelValue )[0];
44 double y = labelGeometryImageFilter->GetCentroid( labelValue )[1];
45 centroids.append( QPoint3D( x * spacing[0], y * spacing[1], 0 ) );
46 }
47 }
48
49 binaryImageToLabelMapFilter->SetInput( NULL );
50 labelMapToLabelImageFilter->SetInput( NULL );
51 labelGeometryImageFilter->SetInput( NULL );
52 vtk2itkConnector->SetInput( NULL );
53
54 return centroids;
55 }
1 int main(int, char *[])
2 {
3 vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New();
4 reader->SetFileName("C:\\Users\\zgb\\Desktop\\1-130.dcm");
5
6 /*************设置窗宽窗位************/
7
8 vtkSmartPointer<vtkImageMapToWindowLevelColors> imageViewer = vtkSmartPointer<vtkImageMapToWindowLevelColors>::New();
9 imageViewer->SetInputConnection(reader->GetOutputPort());
10 imageViewer->SetWindow(2894);
11 imageViewer->SetLevel(-81);
12 imageViewer->Update();
13
14 /*************** 阈值处理**************/
15
16 vtkSmartPointer<vtkImageThreshold> thresholdFilter = vtkSmartPointer<vtkImageThreshold>::New();
17 thresholdFilter->SetInputConnection(imageViewer->GetOutputPort());
18 thresholdFilter->ThresholdByUpper(200);
19 thresholdFilter->SetInValue(255);
20 thresholdFilter->SetOutValue(0);
21 thresholdFilter->Update();
22
23 vtkSmartPointer<vtkImageLuminance> luminanceFilter = vtkSmartPointer<vtkImageLuminance>::New();
24 luminanceFilter->SetInputConnection(thresholdFilter->GetOutputPort());
25 luminanceFilter->Update();
26
27 typedef itk::Image<unsigned char, 2> ImageTypetrans;
28 typedef itk::VTKImageToImageFilter<ImageTypetrans> VTKImageToImageType;
29
30 /************* vtk类型转换为itk类型 ************/
31
32 VTKImageToImageType::Pointer vtkImageToImageFilter = VTKImageToImageType::New();
33 vtkImageToImageFilter->SetInput(luminanceFilter->GetOutput());
34 vtkImageToImageFilter->Update();
35
36 typedef itk::Image<unsigned char, 2> ImageType;
37 ImageType::Pointer image = ImageType::New();
38
39
40 typedef itk::BinaryImageToLabelMapFilter<ImageType>
41 BinaryImageToLabelMapFilterType; //在一幅二值图像中标记连接组件,并产生一个标记组件的集合
42 BinaryImageToLabelMapFilterType::Pointer binaryImageToLabelMapFilter = BinaryImageToLabelMapFilterType::New();//实例化
43 binaryImageToLabelMapFilter->SetInput(vtkImageToImageFilter->GetOutput()); //输入图片
44 binaryImageToLabelMapFilter->Update(); //执行标记连接
45
46 typedef itk::LabelMapToLabelImageFilter<BinaryImageToLabelMapFilterType::OutputImageType, ImageType>
47 LabelMapToLabelImageFilterType; //将这些标记转化为标记的图像
48 LabelMapToLabelImageFilterType::Pointer labelMapToLabelImageFilter = LabelMapToLabelImageFilterType::New();//实例化
49 labelMapToLabelImageFilter->SetInput(binaryImageToLabelMapFilter->GetOutput());//输出作输入
50 labelMapToLabelImageFilter->Update(); //开始执行
51
52 typedef itk::LabelGeometryImageFilter< ImageType > LabelGeometryImageFilterType;
53 LabelGeometryImageFilterType::Pointer labelGeometryImageFilter = LabelGeometryImageFilterType::New();//实例化
54 labelGeometryImageFilter->SetInput( labelMapToLabelImageFilter->GetOutput() );//输入标记的图像
55 labelGeometryImageFilter->Update(); //开始执行
56
57 LabelGeometryImageFilterType::LabelsType allLabels =labelGeometryImageFilter->GetLabels(); //获取标记
58 LabelGeometryImageFilterType::LabelsType::iterator allLabelsIt;//定义迭代器
59
60 for( allLabelsIt=allLabels.begin();allLabelsIt!= allLabels.end(); allLabelsIt++ )
61
62 {
63 LabelGeometryImageFilterType::LabelPixelType labelValue = *allLabelsIt;//定义标记个数
64
65 std::cout << "\tCentroid: "
66 << labelGeometryImageFilter->GetCentroid(labelValue) << std::endl;
67 std::cout << "Number of labels: "
68 << labelGeometryImageFilter->GetNumberOfLabels() << std::endl;
69
70 }
71
72
73 return EXIT_SUCCESS;
74 }