最大圆度概念:
圆度计算(Circularity,Roundness)
1 Roundness = (4 * CV_PI * Area) / (Perimeter * Perimeter ) 2 double getRoundness(std::vector<cv::Point> contour) 3 { 4 double factor = (cv::contourArea(contour) * 4 * CV_PI) / (pow(cv::arcLength(contour, true), 2)); 5 return factor; 6 }
1、代码
1.1 code
1 #include "itkImage.h" 2 #include <vtkSmartPointer.h> 3 #include <vtkPNGWriter.h> 4 #include "itkScalarConnectedComponentImageFilter.h" 5 #include <itkImageToVTKImageFilter.h> 6 #include <itkVTKImageToImageFilter.h> 7 #include <string> 8 #include <iostream> 9 #include<vtkImageShiftScale.h> 10 #include <itkImageRegionIteratorWithIndex.h> 11 #include <itkStatisticsLabelObject.h> 12 #include <itkBinaryImageToShapeLabelMapFilter.h> 13 #include <itkBinaryImageToStatisticsLabelMapFilter.h> 14 #include <itkLabelMapToBinaryImageFilter.h> 15 #include <itkImageFileReader.h> 16 #include <itkImageFileWriter.h> 17 #include <itkMetaImageIO.h> 18 19 using namespace std; 20 void CreateImage(itk::Image<unsigned char, 2>* const image) 21 { 22 // Create an image with 2 connected components 23 itk::Image<unsigned char, 2>::IndexType start = { {0,0} }; 24 start[0] = 0; 25 start[1] = 0; 26 27 itk::Image<unsigned char, 2>::SizeType size; 28 unsigned int NumRows = 100; 29 unsigned int NumCols = 200; 30 size[0] = NumRows; 31 size[1] = NumCols; 32 33 typename itk::Image<unsigned char, 2>::RegionType region(start, size); 34 35 image->SetRegions(region); 36 37 image->Allocate(true);// 全0的像素(黑色) 38 39 // Make a square 40 for (itk::Image<unsigned char, 2>::IndexValueType r = 5; r < 40; r++) 41 { 42 for (itk::Image<unsigned char, 2>::IndexValueType c = 10; c < 50; c++) 43 { 44 itk::Image<unsigned char, 2>::IndexType pixelIndex = { {r,c} }; 45 46 image->SetPixel(pixelIndex, 100);//灰色 47 } 48 } 49 50 // Make another square 51 for (typename itk::Image<unsigned char, 2>::IndexValueType r = 50; r < 70; r++) 52 { 53 for (typename itk::Image<unsigned char, 2>::IndexValueType c = 50; c < 80; c++) 54 { 55 typename itk::Image<unsigned char, 2>::IndexType pixelIndex = { {r,c} }; 56 57 image->SetPixel(pixelIndex, 255);//白色 58 } 59 } 60 61 } 62 void print(const std::string& file, itk::Image<unsigned char, 2>* image) 63 { 64 ofstream fout(file); 65 auto size = image->GetBufferedRegion().GetSize(); 66 for (auto i = 0; i < size[0]; i++) 67 { 68 for (auto j = 0; j < size[1]; j++) 69 { 70 itk::Image<unsigned char, 2>::IndexType index{ {i,j} }; 71 auto c = image->GetPixel(index); 72 fout << (int)c; 73 } 74 fout << std::endl; 75 } 76 } 77 78 using ImageType = itk::Image<unsigned char, 2>; 79 80 ImageType::Pointer CreateMaskImage() 81 { 82 ImageType::Pointer image = ImageType::New(); 83 ImageType::IndexType start; 84 start.Fill(0); 85 86 ImageType::SizeType size; 87 size.Fill(128); 88 89 ImageType::RegionType region; 90 region.SetSize(size); 91 region.SetIndex(start); 92 93 image->SetRegions(region); 94 image->Allocate(); 95 96 using IteratorType = itk::ImageRegionIteratorWithIndex< ImageType >; 97 IteratorType it(image, image->GetRequestedRegion()); 98 99 for (it.GoToBegin(); !it.IsAtEnd(); ++it) 100 { 101 ImageType::IndexType idx = it.GetIndex(); 102 103 // 创建空心圆 C=(50,50),R=15,r=5 104 if ((idx[0] - 50) * (idx[0] - 50) + (idx[1] - 50) * (idx[1] - 50) < 225 && 105 (idx[0] - 50) * (idx[0] - 50) + (idx[1] - 50) * (idx[1] - 50) > 25) 106 it.Set(1); 107 108 // 创建圆 C=(70,80),r=7 109 else if ((idx[0] - 70) * (idx[0] - 70) + (idx[1] - 80) * (idx[1] - 80) < 49) 110 it.Set(1); 111 112 // 创建矩形 C=(100,100),W(120,110) 113 else if (idx[0] >= 100 && idx[0] <= 120 && 114 idx[1] >= 100 && idx[1] <= 110) 115 it.Set(1); 116 117 else 118 it.Set(0); 119 } 120 121 return image; 122 } 123 124 int main(int argc, char *argv[]) 125 { 126 // 1、创建二值图像 127 ImageType::Pointer image = CreateMaskImage();// 128 129 //将itk图片转换成vtk图片 130 auto imageToVtkImage = itk::ImageToVTKImageFilter<itk::Image<unsigned char, 2>>::New(); 131 imageToVtkImage->SetInput(image.GetPointer()); 132 imageToVtkImage->Update();// 只有更新之后,后续使用者才可以拿到真正的数据 133 134 //保存vtk图片为png文件 135 vtkSmartPointer<vtkPNGWriter> writer = vtkSmartPointer<vtkPNGWriter>::New(); 136 writer->SetFileName("D:/documents/vs2019/itk_tutorial/connectcompent/build/RelWithDebInfo/1CreateImage.png"); 137 writer->SetInputData(imageToVtkImage->GetOutput()); 138 writer->Write(); 139 //保存vtk图片像素值到文本文件 140 print("D:/documents/vs2019/itk_tutorial/connectcompent/build/RelWithDebInfo/1CreateImage.txt", image.GetPointer()); 141 142 // 2、过滤连通区域 143 typedef unsigned long LabelType; 144 typedef itk::ShapeLabelObject< LabelType, 2 > LabelObjectType; 145 typedef itk::LabelMap< LabelObjectType > LabelMapType; 146 typedef itk::BinaryImageToShapeLabelMapFilter< ImageType, LabelMapType > I2LType; 147 I2LType::Pointer i2l = I2LType::New(); 148 i2l->SetInput(image); 149 i2l->SetFullyConnected(false); 150 i2l->SetInputForegroundValue(1); 151 i2l->SetOutputBackgroundValue(0); 152 i2l->Update(); 153 154 LabelMapType::Pointer labelMap = i2l->GetOutput(); 155 for (unsigned int label = 1; label <= labelMap->GetNumberOfLabelObjects(); label++) 156 { 157 const LabelObjectType* labelObject = labelMap->GetLabelObject(label); 158 labelObject->Print(std::cout); 159 std::cout << "----------------------------------------" << std::endl; 160 } 161 162 std::vector< LabelObjectType::Pointer > filtered_label_objects; 163 for (LabelMapType::Iterator it(labelMap); !it.IsAtEnd(); ++it) 164 { 165 // 过滤条件 166 if (it.GetLabelObject()->GetRoundness() < 0.95) 167 filtered_label_objects.push_back(it.GetLabelObject()); 168 } 169 170 for (int i = 0; i < filtered_label_objects.size(); i++) 171 { 172 labelMap->RemoveLabelObject(filtered_label_objects[i]); 173 } 174 175 typedef itk::LabelMapToBinaryImageFilter< LabelMapType, ImageType> L2IType; 176 L2IType::Pointer l2i = L2IType::New(); 177 l2i->SetInput(labelMap); 178 l2i->Update(); 179 180 using WriterType = itk::ImageFileWriter<ImageType>; 181 WriterType::Pointer writer1 = WriterType::New(); 182 writer1->SetFileName("mask.mha"); 183 writer1->SetInput(l2i->GetOutput()); 184 writer1->SetImageIO(itk::MetaImageIO::New()); 185 writer1->Update(); 186 187 return EXIT_SUCCESS; 188 }
1.2、生成的mask图片
因为是二值图,像素值只有0和1,直接查看颜色是黑色的,导入slicer中查看。
直接查看:
slicer中查看:
最终保留的圆度最大文件mask.mha,使用slicer打开:
1.3、打印信息
1 ShapeLabelObject (0000022C062D43F0) 2 RTTI typeinfo: class itk::ShapeLabelObject<unsigned long,2> 3 Reference Count: 1 4 LineContainer: 0000022C062D4400 5 Label: 1 6 NumberOfPixels: 616 7 PhysicalSize: 616 8 Perimeter: 127.254 9 NumberOfPixelsOnBorder: 0 10 PerimeterOnBorder: 0 11 PerimeterOnBorderRatio: 0 12 Elongation: 1 13 Flatness: 1 14 Roundness: 0.691393 15 Centroid: [50, 50] 16 BoundingBox: ImageRegion (0000022C062D4430) 17 Dimension: 2 18 Index: [36, 36] 19 Size: [29, 29] 20 EquivalentSphericalRadius: 14.0028 21 EquivalentSphericalPerimeter: 87.9823 22 EquivalentEllipsoidDiameter: [28.0056, 28.0056] 23 PrincipalMoments: [61.9156, 61.9156] 24 PrincipalAxes: 25 1 0 26 0 1 27 FeretDiameter: 0 28 m_OrientedBoundingBoxSize: [0, 0] 29 m_OrientedBoundingBoxOrigin: [0, 0] 30 ---------------------------------------- 31 ShapeLabelObject (0000022C062D3630) 32 RTTI typeinfo: class itk::ShapeLabelObject<unsigned long,2> 33 Reference Count: 1 34 LineContainer: 0000022C062D3640 35 Label: 2 36 NumberOfPixels: 145 37 PhysicalSize: 145 38 Perimeter: 41.524 39 NumberOfPixelsOnBorder: 0 40 PerimeterOnBorder: 0 41 PerimeterOnBorderRatio: 0 42 Elongation: 1 43 Flatness: 1 44 Roundness: 1.02799 45 Centroid: [70, 80] 46 BoundingBox: ImageRegion (0000022C062D3670) 47 Dimension: 2 48 Index: [64, 74] 49 Size: [13, 13] 50 EquivalentSphericalRadius: 6.79374 51 EquivalentSphericalPerimeter: 42.6863 52 EquivalentEllipsoidDiameter: [13.5875, 13.5875] 53 PrincipalMoments: [11.5172, 11.5172] 54 PrincipalAxes: 55 1 0 56 0 1 57 FeretDiameter: 0 58 m_OrientedBoundingBoxSize: [0, 0] 59 m_OrientedBoundingBoxOrigin: [0, 0] 60 ---------------------------------------- 61 ShapeLabelObject (0000022C062D4170) 62 RTTI typeinfo: class itk::ShapeLabelObject<unsigned long,2> 63 Reference Count: 1 64 LineContainer: 0000022C062D4180 65 Label: 3 66 NumberOfPixels: 231 67 PhysicalSize: 231 68 Perimeter: 59.5651 69 NumberOfPixelsOnBorder: 0 70 PerimeterOnBorder: 0 71 PerimeterOnBorderRatio: 0 72 Elongation: 1.91485 73 Flatness: 1.91485 74 Roundness: 0.904522 75 Centroid: [110, 105] 76 BoundingBox: ImageRegion (0000022C062D41B0) 77 Dimension: 2 78 Index: [100, 100] 79 Size: [21, 11] 80 EquivalentSphericalRadius: 8.57494 81 EquivalentSphericalPerimeter: 53.8779 82 EquivalentEllipsoidDiameter: [12.3935, 23.7317] 83 PrincipalMoments: [10, 36.6667] 84 PrincipalAxes: 85 0 1 86 -1 -0 87 FeretDiameter: 0 88 m_OrientedBoundingBoxSize: [0, 0] 89 m_OrientedBoundingBoxOrigin: [0, 0] 90 ----------------------------------------
ITK还提供了itk::BinaryImageToStatisticsLabelMapFilter类,可以提供原图区域的统计信息。
itk::ShapeLabelObject提供的形状信息包括:
1 NumberOfPixels 像素数 2 PhysicalSize 物理尺寸 3 Perimeter 周长 4 NumberOfPixelsOnBorder 边界像素数 5 PerimeterOnBorder 边界周长 6 PerimeterOnBorderRatio 边界周长比 7 Elongation 伸长率 8 Flatness 平整度 9 Roundness 圆度 10 Centroid 质心 11 BoundingBox 包围盒 12 EquivalentSphericalRadius 等效球面半径 13 EquivalentSphericalPerimeter 等效球面周长 14 EquivalentEllipsoidDiameter 等效椭球直径 15 PrincipalMoments 主力矩 16 PrincipalAxes 主轴 17 FeretDiameter
itk::StatisticsLabelObject提供的统计信息包括:
1 Minimum 2 Maximum 3 Mean 4 Sum 5 StandardDeviation 标准差 6 Variance 方差 7 Median 8 Skewness 偏态 9 Kurtosis 峰度 10 WeightedElongation 加权伸长率 11 WeightedFlatness 加权平面度 12 MaximumIndex 13 MinimumIndex 14 CenterOfGravity 重心 15 WeightedPrincipalMoments 加权主力矩 16 WeightedPrincipalAxes 加权主轴
标签:连通,ITK,idx,image,50,圆度,include,Image,itk From: https://www.cnblogs.com/ybqjymy/p/17550375.html