VTK学习笔记(十七)vtkImageEuclideanDistance
1、computes 3D Euclidean DT
vtkImageEuclideanDistance implements the Euclidean DT using Saito’s algorithm. The distance map produced contains the square of the Euclidean distance values.
The algorithm has a o(n^(D+1)) complexity over nxnx…xn images in D dimensions. It is very efficient on relatively small images. Cuisenaire’s algorithms should be used instead if n >> 500. These are not implemented yet.
For the special case of images where the slice-size is a multiple of 2^N with a large N (typically for 256x256 slices), Saito’s algorithm encounters a lot of cache conflicts during the 3rd iteration which can slow it very significantly. In that case, one should use vtkImageEuclideanDistance::SetAlgorithmToSaitoCached() instead for better performance.
References:
T. Saito and J.I. Toriwaki. New algorithms for Euclidean distance transformations of an n-dimensional digitised picture with applications. Pattern Recognition, 27(11). pp. 1551–1565, 1994.
O. Cuisenaire. Distance Transformation: fast algorithms and applications to medical image processing. PhD Thesis, Universite catholique de Louvain, October 1999. http://ltswww.epfl.ch/~cuisenai/papers/oc_thesis.pdf
Definition at line 54 of file vtkImageEuclideanDistance.h.
头文件定义;
/*=========================================================================
Program: Visualization Toolkit
Module: vtkImageEuclideanDistance.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#ifndef vtkImageEuclideanDistance_h
#define vtkImageEuclideanDistance_h
#include "vtkImageDecomposeFilter.h"
#include "vtkImagingGeneralModule.h" // For export macro
#define VTK_EDT_SAITO_CACHED 0
#define VTK_EDT_SAITO 1
class VTKIMAGINGGENERAL_EXPORT vtkImageEuclideanDistance : public vtkImageDecomposeFilter
{
public:
static vtkImageEuclideanDistance* New();
vtkTypeMacro(vtkImageEuclideanDistance, vtkImageDecomposeFilter);
void PrintSelf(ostream& os, vtkIndent indent) override;
vtkSetMacro(Initialize, vtkTypeBool);
vtkGetMacro(Initialize, vtkTypeBool);
vtkBooleanMacro(Initialize, vtkTypeBool);
vtkSetMacro(ConsiderAnisotropy, vtkTypeBool);
vtkGetMacro(ConsiderAnisotropy, vtkTypeBool);
vtkBooleanMacro(ConsiderAnisotropy, vtkTypeBool);
vtkSetMacro(MaximumDistance, double);
vtkGetMacro(MaximumDistance, double);
vtkSetMacro(Algorithm, int);
vtkGetMacro(Algorithm, int);
void SetAlgorithmToSaito() { this->SetAlgorithm(VTK_EDT_SAITO); }
void SetAlgorithmToSaitoCached() { this->SetAlgorithm(VTK_EDT_SAITO_CACHED); }
int IterativeRequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
protected:
vtkImageEuclideanDistance();
~vtkImageEuclideanDistance() override = default;
double MaximumDistance;
vtkTypeBool Initialize;
vtkTypeBool ConsiderAnisotropy;
int Algorithm;
// Replaces "EnlargeOutputUpdateExtent"
virtual void AllocateOutputScalars(vtkImageData* outData, int outExt[6], vtkInformation* outInfo);
int IterativeRequestInformation(vtkInformation* in, vtkInformation* out) override;
int IterativeRequestUpdateExtent(vtkInformation* in, vtkInformation* out) override;
private:
vtkImageEuclideanDistance(const vtkImageEuclideanDistance&) = delete;
void operator=(const vtkImageEuclideanDistance&) = delete;
};
#endif
参考:vtkImageEuclideanDistance Class Reference
2、示例程序
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2); // VTK was built with vtkRenderingOpenGL2
VTK_MODULE_INIT(vtkInteractionStyle);
/**********************************************************************
文件名: 4.1_ReadSeriesImages1.cpp
Copyright (c) 张晓东, 罗火灵. All rights reserved.
更多信息请访问:
http://www.vtkchina.org (VTK中国)
http://blog.csdn.net/www_doling_net (东灵工作室)
**********************************************************************/
/**********************************************************************
文件名: 4.2_Import3DS.cpp
Copyright (c) 张晓东, 罗火灵. All rights reserved.
更多信息请访问:
http://www.vtkchina.org (VTK中国)
http://blog.csdn.net/www_doling_net (东灵工作室)
**********************************************************************/
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderWindow.h>
#include <vtkImageThreshold.h>
#include <vtkImageEuclideanDistance.h>
int main()
{
vtkSmartPointer<vtkImageData> img = vtkSmartPointer<vtkImageData>::New();
img->SetDimensions(16, 16, 1);
#if VTK_MAJOR_VERSION <= 5
img->SetNumberOfScalarComponents(1);
img->SetScalarTypeToUnsignedChar();
img->AllocateScalars();
#else
img->AllocateScalars(VTK_UNSIGNED_CHAR, 1);
#endif
unsigned char *ptr = (unsigned char*)img->GetScalarPointer();
for (int i = 0; i<16 * 16 * 1; i++)
{
if (i%16 == i/16)
{
*ptr++ = 0;
}
else
{
*ptr++ = 255;
}
}
vtkSmartPointer<vtkImageThreshold> threshould =
vtkSmartPointer<vtkImageThreshold>::New();
//threshould->SetInputConnection(reader->GetOutputPort());
threshould->SetInputData(img);
threshould->ThresholdByUpper(90);
threshould->SetInValue(255);
threshould->SetOutValue(0);
threshould->Update();
vtkSmartPointer<vtkImageEuclideanDistance> dist =
vtkSmartPointer<vtkImageEuclideanDistance>::New();
dist->SetInputConnection(threshould->GetOutputPort());
dist->SetAlgorithmToSaitoCached();
dist->Update();
vtkSmartPointer<vtkImageData> distimg = dist->GetOutput();
int inputDataType = distimg->GetScalarType();
if (inputDataType == VTK_DOUBLE)
{
double* dstptr = (double*)distimg->GetScalarPointer();
for (int i = 0; i < 16 * 16 * 1; i++)
{
std::cout << *dstptr++ << "\t";
if ((i + 1) % 16 == 0)
{
std::cout << std::endl;
}
}
}
vtkSmartPointer<vtkImageActor> redActor =
vtkSmartPointer<vtkImageActor>::New();
//redActor->SetInputData(img); //VTK5的代码为SetInput();
//redActor->SetInputData(threshould->GetOutput());
redActor->SetInputData(dist->GetOutput());
double redViewport[4] = { 0.0, 0.0, 1.0, 1.0 };
vtkSmartPointer<vtkRenderer> redRenderer =
vtkSmartPointer<vtkRenderer>::New();
redRenderer->SetViewport(redViewport);
redRenderer->AddActor(redActor);
redRenderer->ResetCamera();
redRenderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(redRenderer);
renderWindow->SetSize(640, 480);
renderWindow->Render();
renderWindow->SetWindowName("CreateVTKImageData");
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkInteractorStyleImage> style =
vtkSmartPointer<vtkInteractorStyleImage>::New();
renderWindowInteractor->SetInteractorStyle(style);
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
输出结果:
返回结果与使用说明描述一致
vtkImageEuclideanDistance implements the Euclidean DT using Saito’s algorithm. The distance map produced contains the square
of the Euclidean distance values.
0 1 2 5 8 13 18 25 32 41 50 61 72 85 98 113
1 0 1 2 5 8 13 18 25 32 41 50 61 72 85 98
2 1 0 1 2 5 8 13 18 25 32 41 50 61 72 85
5 2 1 0 1 2 5 8 13 18 25 32 41 50 61 72
8 5 2 1 0 1 2 5 8 13 18 25 32 41 50 61
13 8 5 2 1 0 1 2 5 8 13 18 25 32 41 50
18 13 8 5 2 1 0 1 2 5 8 13 18 25 32 41
25 18 13 8 5 2 1 0 1 2 5 8 13 18 25 32
32 25 18 13 8 5 2 1 0 1 2 5 8 13 18 25
41 32 25 18 13 8 5 2 1 0 1 2 5 8 13 18
50 41 32 25 18 13 8 5 2 1 0 1 2 5 8 13
61 50 41 32 25 18 13 8 5 2 1 0 1 2 5 8
72 61 50 41 32 25 18 13 8 5 2 1 0 1 2 5
85 72 61 50 41 32 25 18 13 8 5 2 1 0 1 2
98 85 72 61 50 41 32 25 18 13 8 5 2 1 0 1
113 98 85 72 61 50 41 32 25 18 13 8 5 2 1 0