手动创建一个黑色0的图片,其中加入两个矩形,一个为像素值为100的灰色;另一个是像素值为255的白色
将图片输出为png和TXT
用连通区域算子计算出连通区域1,2,3
将连通区域输出到TXT
为了能够显示像素为1,2,3的图片,放大这些像素
输出放大后的像素图片到png
输出放大后的像素图片到TXT
#include "itkImage.h"
#include <vtkSmartPointer.h>
#include <vtkPNGWriter.h>
#include "itkScalarConnectedComponentImageFilter.h"
#include <itkImageToVTKImageFilter.h>
#include <itkVTKImageToImageFilter.h>
#include <string>
#include <iostream>
#include<vtkImageShiftScale.h>
void CreateImage(itk::Image<unsigned char, 2>* const image)
{
// Create an image with 2 connected components
itk::Image<unsigned char, 2>::IndexType start = { {0,0} };
start[0] = 0;
start[1] = 0;
itk::Image<unsigned char, 2>::SizeType size;
unsigned int NumRows = 100;
unsigned int NumCols = 200;
size[0] = NumRows;
size[1] = NumCols;
typename itk::Image<unsigned char, 2>::RegionType region(start, size);
image->SetRegions(region);
image->Allocate(true);// 全0的像素(黑色)
// Make a square
for (itk::Image<unsigned char, 2>::IndexValueType r = 5; r < 40; r++)
{
for (itk::Image<unsigned char, 2>::IndexValueType c = 10; c < 50; c++)
{
itk::Image<unsigned char, 2>::IndexType pixelIndex = { {r,c} };
image->SetPixel(pixelIndex, 100);//灰色
}
}
// Make another square
for (typename itk::Image<unsigned char, 2>::IndexValueType r = 50; r < 70; r++)
{
for (typename itk::Image<unsigned char, 2>::IndexValueType c = 50; c < 80; c++)
{
typename itk::Image<unsigned char, 2>::IndexType pixelIndex = { {r,c} };
image->SetPixel(pixelIndex, 255);//白色
}
}
}
void print(const std::string& file, itk::Image<unsigned char, 2>* image)
{
ofstream fout(file);
auto size = image->GetBufferedRegion().GetSize();
for (auto i = 0; i < size[0]; i++)
{
for (auto j = 0; j < size[1]; j++)
{
itk::Image<unsigned char, 2>::IndexType index{ {i,j} };
auto c = image->GetPixel(index);
fout << (int)c;
}
fout << std::endl;
}
}
int main(int argc, char *argv[])
{
short distanceThreshold = 4;
auto image = itk::Image<unsigned char, 2>::New();
CreateImage(image.GetPointer());// 创建一个背景为黑色的,包含两个长方形区域(一个为灰色100,一个为白色255)的图片
image->Update();
//将itk图片转换成vtk图片
auto imageToVtkImage = itk::ImageToVTKImageFilter<itk::Image<unsigned char, 2>>::New();
imageToVtkImage->SetInput(image.GetPointer());
imageToVtkImage->Update();// 只有更新之后,后续使用者才可以拿到真正的数据
//保存vtk图片为png文件
vtkSmartPointer<vtkPNGWriter> writer = vtkSmartPointer<vtkPNGWriter>::New();
writer->SetFileName("E:/1/1CreateImage.png");
writer->SetInputData(imageToVtkImage->GetOutput());
writer->Write();
//保存vtk图片像素值到文本文件
print("E:/1/1CreateImage.txt", image.GetPointer());
//从vtk图片得到连通区域:1,2,3(每个连通区域中的像素点的值)
auto connected = itk::ScalarConnectedComponentImageFilter<itk::Image<unsigned char, 2>, itk::Image<unsigned char, 2>>::New();
connected->SetInput(image);
connected->SetDistanceThreshold(distanceThreshold);
connected->Update();
//输出vtk图片连通区域:1,2,3
print("E:/1/2ScalarConnectedComponentImage.txt", connected->GetOutput());
//连通区域图片的像素值为label值,只有1,2,3。
//每个连通区域的像素都用一个Id值存储,由于1,2,3这种值作为像素值的话都是接近黑色,
//所以要想打印出区分明显的图片需要vtkImageShiftScale变换
imageToVtkImage->SetInput(connected->GetOutput());
imageToVtkImage->Update();
double range[2];
imageToVtkImage->GetOutput()->GetScalarRange(range);
vtkSmartPointer<vtkImageShiftScale>scale = vtkSmartPointer<vtkImageShiftScale>::New();
scale->SetInputData(imageToVtkImage->GetOutput());
scale->SetScale(255 / range[1]);//大范围的最大值除以小范围的最大值得到变换的放大倍数:(1,2, 3)->(85, 170, 255)
scale->Update();
//将变换后的图片保存到png
writer->SetFileName("E:/1/3ConnectedComponentImage.png");
writer->SetInputData(scale->GetOutput());
writer->Write();
auto vtkImageToImage = itk::VTKImageToImageFilter<itk::Image<unsigned char, 2>>::New();
vtkImageToImage->SetInput(scale->GetOutput());
vtkImageToImage->Update();
//输出连通区域:(85, 170, 255)
print("E:/1/3ConnectedComponentImage.txt", vtkImageToImage->GetOutput());
std::cout << "return ok" << std::endl;
return EXIT_SUCCESS;
}
1CreateImage.png
1CreateImage.txt
2ScalarConnectedComponentImage.txt
3ConnectedComponentImage.png
3ConnectedComponentImage.txt