VTK拾取种子点、ITK区域生长

前言

区域生长算法已被证明是一种有效的图像分割方法。区域生长算法的基本思想是从一个或多个种子区域(该种子区域被认为在要分割的对象内部)开始,评估与该区域相邻的像素,以确定它们是否也应被视为对象的一部分。如果邻域像素满足要求,则它们被添加到该区域,并且只要有新像素被添加到该区域,区域生长过程就继续。区域增长算法根据用于决定像素是否应包含在区域中的标准、用于确定邻居的连通性类型以及用于访问相邻像素的策略而变化。

开发环境

windows10、VS2017 、VTK8.2、ITK5.0.1

运行结果

区域生长

使用方法

按住ctrl键,用鼠标左键拾取种子点。区域生长默认的范围是[226,3071],若鼠标点选的像素值在该范围之外,则不做任何处理;若像素值在该范围内,则进行区域生长,并将分割后的图像进行彩色映射和原始图像叠加。

代码

//有些头文件用不到
#pragma once
#include "pch.h"
#include <iostream>

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);

#include <vtkImageData.h>
#include <vtkProperty.h>
#include <vtkDataSetMapper.h>
#include <vtkRendererCollection.h>
#include <itkImageToVTKImageFilter.h>
#include <vtkPolyDataMapper.h>
#include <vtkDICOMImageReader.h>
#include <vtkPolyData.h>
#include <vtkPointData.h>
#include <vtkAxesActor.h>
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkMarchingCubes.h"
#include "vtkStripper.h"
#include "vtkActor.h"
#include "vtkSmoothPolyDataFilter.h"
#include "vtkPolyDataNormals.h"
#include "vtkImageShrink3D.h"
#include "vtkDecimatePro.h"
#include "vtkProperty.h"
#include <vtkInteractorStyleImage.h>
#include <vector>
#include <string>

#include <vtkSmartPointer.h>  
#include <vtkImageActor.h>  
#include <vtkRenderer.h>  
#include <vtkRenderWindow.h>  
#include <vtkRenderWindowInteractor.h>  
#include <vtkImageViewer2.h>
#include <vtkImageSliceMapper.h>
#include <vtkPNGReader.h>
#include <vtkSTLReader.h>
#include <vtkTexture.h>
#include <vtkTextureMapToCylinder.h>
#include <vtkImageFlip.h>
#include <vtkImageGradient.h>
#include <vtkImageGradient.h>
#include <vtkImageMagnitude.h>
#include <vtkImageShiftScale.h>
#include <vtkImageHybridMedian2D.h>
#include <vtkSphereSource.h>
#include <vtkTextProperty.h>
#include <vtkProperty2D.h>
#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkSliderWidget.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkCommand.h>
#include <vtkWidgetEvent.h>
#include <vtkCallbackCommand.h>
#include <vtkWidgetEventTranslator.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkSliderWidget.h>
#include <vtkSliderRepresentation2D.h>
#include <vtkProperty.h>

#include "itkImageToVTKImageFilter.h"
#include "itkJPEGImageIOFactory.h"
#include "itkRGBPixel.h"
#include "itkImage.h"
#include "itkGDCMImageIO.h"
#include "itkGDCMSeriesFileNames.h"
#include "itkVTKImageToImageFilter.h"
#include "itkRescaleIntensityImageFilter.h"
#include "itkImageSeriesReader.h"
#include "itkImageSeriesWriter.h"
#include "itkCurvatureFlowImageFilter.h"
#include "itkConnectedThresholdImageFilter.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkCastImageFilter.h"
#include "itkPNGImageIOFactory.h"
#include "itksys/SystemTools.hxx"
#include "itkImageRegionIterator.h"
#include <itkImage.h>
#include <itkImageFileReader.h>
#include <itkImageFileWriter.h>  
#include <itkPNGImageIOFactory.h>  
#include <itkConnectedThresholdImageFilter.h>  
#include <itkImageSeriesReader.h>  
#include <itkGDCMImageIO.h>  
#include <itkImageToVTKImageFilter.h>  
#include <vtkLookupTable.h>
#include <vtkImageProperty.h>
#include <vtkImageMapToColors.h>
#include "vtkImageViewer2.h"

using namespace std;
typedef short PixelType;
const unsigned int   Dimension = 2;
typedef itk::Image< PixelType, Dimension > Input2dImageType;
typedef itk::GDCMImageIO   ImageIOType;//GDCMImageIO读DICOM
ImageIOType::Pointer gdcmImageIO = ImageIOType::New();
typedef itk::ImageFileReader< Input2dImageType > ReaderType2d;
ReaderType2d::Pointer reader2d = ReaderType2d::New();
vtkSmartPointer<vtkImageViewer2> viewer = vtkSmartPointer<vtkImageViewer2>::New();

vtkSmartPointer<vtkImageData> itkToVtk(Input2dImageType::Pointer image)
{
    
    
	typedef itk::ImageToVTKImageFilter< Input2dImageType> itkTovtkFilterType;
	itkTovtkFilterType::Pointer itkTovtkImageFilter = itkTovtkFilterType::New();
	itkTovtkImageFilter->SetInput(image);//设置图像数据从ITK转向VTK
	itkTovtkImageFilter->Update();

	return itkTovtkImageFilter->GetOutput();
}

Input2dImageType::Pointer connectedThreshold(int range[2], Input2dImageType::Pointer itkImage, Input2dImageType::IndexType seed)
{
    
    
	typedef itk::ConnectedThresholdImageFilter< Input2dImageType, Input2dImageType > ConnectedFilterType;
	ConnectedFilterType::Pointer connectedThres = ConnectedFilterType::New();
	connectedThres->SetInput(itkImage);
	connectedThres->SetLower(range[0]);
	connectedThres->SetUpper(range[1]);
	connectedThres->SetReplaceValue(3071);
	connectedThres->AddSeed(seed);
	connectedThres->Update();
	return connectedThres->GetOutput();
}

class LineInteractorStyle : public vtkInteractorStyleTrackballCamera
{
    
    
public:
	static LineInteractorStyle* New();
	vtkTypeMacro(LineInteractorStyle, vtkInteractorStyleTrackballCamera);

	~LineInteractorStyle();
	virtual void OnLeftButtonDown();
	virtual void OnRightButtonDown();
	
	Input2dImageType::Pointer itkImage = nullptr;
private:
	
};

vtkStandardNewMacro(LineInteractorStyle);

LineInteractorStyle::~LineInteractorStyle()
{
    
    
}

void LineInteractorStyle::OnLeftButtonDown()
{
    
    
	if (this->Interactor->GetControlKey()) {
    
    
		//视口坐标
		int *clickPos;
		clickPos = this->GetInteractor()->GetEventPosition();
		double point1[3]{
    
     0 };
		point1[0] = clickPos[0];
		point1[1] = clickPos[1];

		//世界坐标
		double worldPoint[3]{
    
     0 };
		this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->SetDisplayPoint(point1[0], point1[1], 0);
		this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->DisplayToWorld();
		worldPoint[0] = (this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetWorldPoint())[0];
		worldPoint[1] = (this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetWorldPoint())[1];
		worldPoint[2] = (this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetWorldPoint())[2];


		typedef itk::Point< double, 2 > PointType;
		PointType point;
		point[0] = worldPoint[0];
		point[1] = worldPoint[1];
		Input2dImageType::IndexType pixelIndex;
		bool isInside =  this->itkImage->TransformPhysicalPointToIndex(point, pixelIndex);
		if (!isInside)
			return;
		int range[2] = {
    
     226,3071 };
		Input2dImageType::PixelType value = this->itkImage->GetPixel(pixelIndex);
		if (value<range[0] || value>range[1])
			return;
		Input2dImageType::Pointer image1 =  connectedThreshold(range, this->itkImage, pixelIndex);
		vtkSmartPointer<vtkImageData> image2 = itkToVtk(image1);
		vtkSmartPointer<vtkLookupTable> pColorTable = vtkSmartPointer<vtkLookupTable>::New();
		pColorTable->SetNumberOfColors(2);
		pColorTable->SetTableRange(0, 3071);
		pColorTable->SetTableValue(0, 0.0, 0.0, 0.0, 0.0);
		static bool flag = true;
		if (flag)
			pColorTable->SetTableValue(1, 0, 1, 0, 1.0);
		else 
			pColorTable->SetTableValue(1, 0, 0, 1, 1.0);
		flag = !flag;
		pColorTable->Build();
		
		vtkSmartPointer<vtkImageMapToColors> colorMap =
			vtkSmartPointer<vtkImageMapToColors>::New();
		colorMap->SetInputData(image2);
		colorMap->SetLookupTable(pColorTable);
		colorMap->Update();
	
		vtkSmartPointer<vtkImageActor> colorActor =
			vtkSmartPointer<vtkImageActor>::New();
		colorActor->SetInputData(colorMap->GetOutput());
		colorActor->SetInterpolate(false);
		viewer->GetRenderer()->AddActor(colorActor);
		viewer->Render();
	}
	else {
    
    
		vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
	}
}

void LineInteractorStyle::OnRightButtonDown()
{
    
    
	vtkInteractorStyleTrackballCamera::OnRightButtonDown();
}

Input2dImageType::Pointer read2dImage(const char * path)
{
    
    
	reader2d->SetFileName(path);
	reader2d->SetImageIO(gdcmImageIO);
	reader2d->Update();
	return reader2d->GetOutput();
}

void showImage(Input2dImageType::Pointer itkImage)
{
    
    
	viewer->SetInputData(itkToVtk(itkImage));
	viewer->SetSliceOrientationToXY();
	viewer->Render();
	viewer->GetRenderer()->SetBackground(0.5, 0.5, 0.5);

	vtkSmartPointer<LineInteractorStyle> style = vtkSmartPointer<LineInteractorStyle>::New();
	style->itkImage = itkImage;
	vtkSmartPointer<vtkRenderWindowInteractor> rwi =
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	//设置交互属性
	viewer->SetupInteractor(rwi);
	viewer->GetRenderer()->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style);
	rwi->Start();
	viewer->Render();

}

int main()
{
    
    
	Input2dImageType::Pointer itkImage = read2dImage("C:\\Users\\Desktop\\segment\\IM12");
	showImage(itkImage);
	return 0;
}


猜你喜欢

转载自blog.csdn.net/l1783111653/article/details/108876968