ITK 计算质心

发布时间 2023-07-13 14:39:42作者: 一杯清酒邀明月

  通过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 }