Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
129c0ab
if a second image - check if it is the same as the first one
benpresles Dec 25, 2016
75f88a6
added the possibility to write the RTStruct as a nifti image
benpresles Apr 25, 2017
fadc8fa
added first order statistics to the image statistics tool
benpresles Jun 11, 2017
84ba626
added first order statistics from image
benpresles Jun 23, 2017
ed11152
changed the clitkImageStatistics output
benpresles Jul 11, 2017
e0172e4
changed ImageStatistics output + normalised the histogram
benpresles Jul 11, 2017
e210c63
corrected a bug - save RTStruct in mha is possible again
benpresles Aug 10, 2017
1ca1e37
improve blur image tool - double ouput pixel type is supported now
benpresles Jan 21, 2019
a80ac57
add cmath header
benpresles Jun 7, 2019
badac5b
add c++11 compilation flag
benpresles Jun 8, 2019
d5634de
solve compilation problems on linux with qt5
benpresles Jun 25, 2019
96754d6
improve the DicomRTStruct2Image tool
benpresles Jul 9, 2019
c471354
try to fix the linking issues I have on linux with Qt5
benpresles Jul 9, 2019
185b452
try to fix the linking issue I have on linux with VTK-7.1.1 staticall…
benpresles Jul 10, 2019
4308c33
comment an unnecessary message
benpresles Jul 10, 2019
1c484fe
resolve a file handling bug
benpresles Jul 21, 2019
f34f949
resolve a file handling bug - v2
benpresles Jul 22, 2019
e52bb8c
add a tolerance parameter in the clitkDicomRTStruct2Image tool
benpresles Jul 25, 2019
e7b6a4d
allow to save the splited images in nii, nii.gz or mha
benpresles Aug 10, 2019
104647f
change the spacing comparison to a softer version
benpresles Aug 10, 2019
a2384b5
correction of a bug related to templates in clitkAffineTransform
benpresles Dec 22, 2019
4eafea9
changes that could not be git cherry picked
benpresles Dec 27, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,25 @@ endif()
#=========================================================

target_link_libraries(clitkCommon ${VTK_LIBRARIES} ${ITK_LIBRARIES})
# I have some linking problems on linux if VTK 7.1.1 (at least) is built statically - It asks for Qt5::X11Extras - I do not know why
# First workaround - link clitkCommon with Qt5::X11Extras - Qt5::X11Extras is not necessary if VTK is built dynamically
# Second workaround - oblige the user to recompile VTK as a dynamic library (better solution)
if(UNIX AND NOT APPLE)
if(vv_QT_VERSION VERSION_EQUAL "5") #5
if(VTK_VERSION VERSION_EQUAL "7.1.1") #7.1.1
#message(${VTK_DIR})
list(GET VTK_LIBRARIES 0 FIRST_VTK_ELEMENT)
#message(${FIRST_VTK_ELEMENT})
file(GLOB FIRST_VTK_LIB ${VTK_DIR}/../../*${FIRST_VTK_ELEMENT}*.a)
#message(${FIRST_VTK_LIB})
if(EXISTS ${FIRST_VTK_LIB})
message(FATAL_ERROR "VTK is built as a statically library - you need to recompile VTK and/or ITK as dynamic libraries")
#find_package(Qt5X11Extras REQUIRED)
#target_link_libraries(clitkCommon Qt5::X11Extras)
endif()
endif()
endif()
endif()

add_library(clitkDicomRTStruct STATIC
clitkDicomRT_Contour.cxx
Expand Down
2 changes: 1 addition & 1 deletion common/clitkCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ namespace clitk {
//--------------------------------------------------------------------
// when everything goes wrong
#define WHEREAMI "[ " << __FILE__ << " ] line " << __LINE__
#define FATAL(a) { std::cerr << "ERROR in " << WHEREAMI << ": " << a; exit(0); }
#define FATAL(a) { std::cerr << "ERROR in " << WHEREAMI << ": " << a << std::endl; exit(0); }

//--------------------------------------------------------------------
// GGO with modified struct name
Expand Down
92 changes: 61 additions & 31 deletions common/clitkDicomRTStruct2ImageFilter.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
// clitk
#include "clitkDicomRTStruct2ImageFilter.h"
#include "clitkImageCommon.h"
#include "vvImageWriter.h"

// vtk
#include <vtkVersion.h>
Expand All @@ -32,6 +33,7 @@
#include <vtkLinearExtrusionFilter.h>
#include <vtkMetaImageWriter.h>
#include <vtkXMLPolyDataWriter.h>
#include <vtkTransformPolyDataFilter.h>


//--------------------------------------------------------------------
Expand Down Expand Up @@ -107,13 +109,19 @@ void clitk::DicomRTStruct2ImageFilter::SetImage(vvImage::Pointer image)
{
if (image->GetNumberOfDimensions() != 3) {
std::cerr << "Error. Please provide a 3D image." << std::endl;
exit(0);
exit(EXIT_FAILURE);
}
mSpacing.resize(3);
mOrigin.resize(3);
mSize.resize(3);
mDirection.resize(3);
mTransformMatrix = image->GetTransform()[0]->GetMatrix();
//mTransformMatrix = image->GetTransform()[0]->GetMatrix();
mTransformMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
for(unsigned int i=0;i<4;i++) {
for(unsigned int j=0;j<4;j++) {
mTransformMatrix->SetElement(i,j,image->GetTransform()[0]->GetMatrix()->GetElement(i,j));
}
}
for(unsigned int i=0; i<3; i++) {
mSpacing[i] = image->GetSpacing()[i];
mOrigin[i] = image->GetOrigin()[i];
Expand All @@ -132,7 +140,7 @@ void clitk::DicomRTStruct2ImageFilter::SetImageFilename(std::string f)
itk::ImageIOBase::Pointer header = clitk::readImageHeader(f);
if (header->GetNumberOfDimensions() < 3) {
std::cerr << "Error. Please provide a 3D image instead of " << f << std::endl;
exit(0);
exit(EXIT_FAILURE);
}
if (header->GetNumberOfDimensions() > 3) {
std::cerr << "Warning dimension > 3 are ignored" << std::endl;
Expand All @@ -149,6 +157,18 @@ void clitk::DicomRTStruct2ImageFilter::SetImageFilename(std::string f)
for(unsigned int j=0; j<3; j++)
mDirection[i][j] = header->GetDirection(i)[j];
}
//cf. AddItkImage function in vvImage.txx
mTransformMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
mTransformMatrix->Identity();
for(unsigned int i=0; i<3; i++) {
double tmp = 0;
for(unsigned int j=0; j<3; j++) {
mTransformMatrix->SetElement(i,j,mDirection[i][j]);
tmp -= mDirection[i][j] * mOrigin[j];
}
tmp += mOrigin[i];
mTransformMatrix->SetElement(i,3,tmp);
}
}
//--------------------------------------------------------------------

Expand Down Expand Up @@ -182,11 +202,11 @@ void clitk::DicomRTStruct2ImageFilter::Update()
{
if (!mROI) {
std::cerr << "Error. No ROI set, please use SetROI." << std::endl;
exit(0);
exit(EXIT_FAILURE);
}
if (!ImageInfoIsSet()) {
std::cerr << "Error. Please provide image info (spacing/origin) with SetImageFilename" << std::endl;
exit(0);
exit(EXIT_FAILURE);
}

// Get Mesh
Expand All @@ -206,7 +226,7 @@ void clitk::DicomRTStruct2ImageFilter::Update()

// Get bounds
double *bounds=mesh->GetBounds();

/*
//Change mOrigin, mSize and mSpacing with respect to the directions
// Spacing is influenced by input direction
std::vector<double> tempSpacing;
Expand Down Expand Up @@ -238,7 +258,7 @@ void clitk::DicomRTStruct2ImageFilter::Update()
}
mSize[i] = lrint(tempSize[i]);
}

*/
// Compute origin
std::vector<double> origin;
origin.resize(3);
Expand All @@ -259,7 +279,18 @@ void clitk::DicomRTStruct2ImageFilter::Update()
extend[i] = mSize[i]-1;
}
}

//Apply the transform to the mesh
vtkSmartPointer<vtkTransform> outputLabelmapGeometryTransform = vtkSmartPointer<vtkTransform>::New();
outputLabelmapGeometryTransform->SetMatrix(mTransformMatrix);
// Apparently the inverse is wrong...
//outputLabelmapGeometryTransform->Inverse();
vtkSmartPointer<vtkTransformPolyDataFilter> transformPolyDataFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
#if VTK_MAJOR_VERSION <= 5
transformPolyDataFilter->SetInput(mesh);
#else
transformPolyDataFilter->SetInputData(mesh);
#endif
transformPolyDataFilter->SetTransform(outputLabelmapGeometryTransform);
// Create new output image
mBinaryImage = vtkSmartPointer<vtkImageData>::New();
#if VTK_MAJOR_VERSION <= 5
Expand All @@ -281,11 +312,7 @@ void clitk::DicomRTStruct2ImageFilter::Update()

// Extrude
vtkSmartPointer<vtkLinearExtrusionFilter> extrude=vtkSmartPointer<vtkLinearExtrusionFilter>::New();
#if VTK_MAJOR_VERSION <= 5
extrude->SetInput(mesh);
#else
extrude->SetInputData(mesh);
#endif
extrude->SetInputConnection(transformPolyDataFilter->GetOutputPort());
///We extrude in the -slice_spacing direction to respect the FOCAL convention (NEEDED !)
extrude->SetVector(0, 0, -mSpacing[2]);

Expand All @@ -295,11 +322,7 @@ void clitk::DicomRTStruct2ImageFilter::Update()
//http://www.nabble.com/Bug-in-vtkPolyDataToImageStencil--td23368312.html#a23370933
sts->SetTolerance(0);
sts->SetInformationInput(mBinaryImage);
#if VTK_MAJOR_VERSION <= 5
sts->SetInput(extrude->GetOutput());
#else
sts->SetInputConnection(extrude->GetOutputPort(0));
#endif
//sts->SetInput(mesh);

vtkSmartPointer<vtkImageStencil> stencil=vtkSmartPointer<vtkImageStencil>::New();
Expand All @@ -316,22 +339,26 @@ void clitk::DicomRTStruct2ImageFilter::Update()
stencil->ReverseStencilOn();
stencil->Update();

/*
vtkSmartPointer<vtkMetaImageWriter> w = vtkSmartPointer<vtkMetaImageWriter>::New();
w->SetInput(stencil->GetOutput());
w->SetFileName("binary2.mhd");
w->Write();
*/

mBinaryImage->ShallowCopy(stencil->GetOutput());

vvImage::Pointer vvBinaryImage = vvImage::New();
vtkSmartPointer<vtkTransform> vvBinaryImageT = vtkSmartPointer<vtkTransform>::New();
vvBinaryImageT->SetMatrix(mTransformMatrix);
vvBinaryImage->AddVtkImage(mBinaryImage, vvBinaryImageT);

if (mWriteOutput) {
typedef itk::Image<unsigned char, 3> ImageType;
typedef itk::VTKImageToImageFilter<ImageType> ConnectorType;
ConnectorType::Pointer connector = ConnectorType::New();
connector->SetInput(GetOutput());
connector->Update();
clitk::writeImage<ImageType>(connector->GetOutput(), mOutputFilename);
//typedef itk::Image<unsigned char, 3> ImageType;
//typedef itk::VTKImageToImageFilter<ImageType> ConnectorType;
//ConnectorType::Pointer connector = ConnectorType::New();
//connector->SetInput(GetOutput());
//connector->Update();
//clitk::writeImage<ImageType>(connector->GetOutput(), mOutputFilename);
vvImageWriter::Pointer writer = vvImageWriter::New();
writer->SetInput(vvBinaryImage);
if (!vvBinaryImage->GetTransform().empty())
writer->SetSaveTransform(true);
writer->SetOutputFileName(mOutputFilename);
writer->Update();
}
}
//--------------------------------------------------------------------
Expand All @@ -341,7 +368,10 @@ void clitk::DicomRTStruct2ImageFilter::Update()
//--------------------------------------------------------------------
vtkImageData * clitk::DicomRTStruct2ImageFilter::GetOutput()
{
assert(mBinaryImage);
//assert(mBinaryImage);
if (mBinaryImage == NULL) {
FATAL("The binary RTStruct image is NULL");
}
return mBinaryImage;
}
//--------------------------------------------------------------------
Expand Down
22 changes: 11 additions & 11 deletions common/clitkDicomRTStruct2ImageFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,17 @@ namespace clitk {

//--------------------------------------------------------------------

template <int Dimension>
typename itk::Image<unsigned char,Dimension>::ConstPointer clitk::DicomRTStruct2ImageFilter::GetITKOutput()
{
assert(mBinaryImage);
typedef itk::Image<unsigned char,Dimension> ConnectorImageType;
typedef itk::VTKImageToImageFilter <ConnectorImageType> ConnectorType;
typename ConnectorType::Pointer connector = ConnectorType::New();
connector->SetInput(mBinaryImage);
connector->Update();
return connector->GetOutput();
}
//template <int Dimension>
//typename itk::Image<unsigned char,Dimension>::ConstPointer clitk::DicomRTStruct2ImageFilter::GetITKOutput()
//{
// assert(mBinaryImage);
// typedef itk::Image<unsigned char,Dimension> ConnectorImageType;
// typedef itk::VTKImageToImageFilter <ConnectorImageType> ConnectorType;
// typename ConnectorType::Pointer connector = ConnectorType::New();
// connector->SetInput(mBinaryImage);
// connector->Update();
// return connector->GetOutput();
//}
//--------------------------------------------------------------------
#endif // CLITKDICOMRT_TRUCT2IMAGEFILTER_H

59 changes: 32 additions & 27 deletions common/clitkDicomRT_Contour.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,7 @@ void clitk::DicomRT_Contour::UpdateDicomItem()
double * p = mData->GetPoint(i);
points[i*3] = p[0];
points[i*3+1] = p[1];
#if VTK_MAJOR_VERSION <= 5
points[i*3+1] = p[2];
#else
points[i*3+1] = p[2]-0.5;
#endif
}

// Get attribute
Expand All @@ -96,7 +92,7 @@ void clitk::DicomRT_Contour::UpdateDicomItem()
at.SetFromDataElement( contourdata );

// Set attribute
at.SetValues(&points[0], points.size(), false);
at.SetValues(&points[0], points.size());
DD(at.GetValues()[0]);

DD("replace");
Expand Down Expand Up @@ -151,7 +147,10 @@ bool clitk::DicomRT_Contour::Read(gdcm::Item * item)
at.SetFromDataElement( contourdata );
const double* points = at.GetValues();
// unsigned int npts = at.GetNumberOfValues() / 3;
assert(at.GetNumberOfValues() == static_cast<unsigned int>(mNbOfPoints)*3);
//assert(at.GetNumberOfValues() == static_cast<unsigned int>(mNbOfPoints)*3);
if (at.GetNumberOfValues() != static_cast<unsigned int>(mNbOfPoints)*3) {
FATAL("The number of contour points is inconsistent with the number of triplets defining the contour");
}

// Organize values
mData = vtkSmartPointer<vtkPoints>::New();
Expand All @@ -161,19 +160,16 @@ bool clitk::DicomRT_Contour::Read(gdcm::Item * item)
double p[3];
p[0] = points[i*3];
p[1] = points[i*3+1];
#if VTK_MAJOR_VERSION <= 5
p[2] = points[i*3+2];
#else
p[2] = points[i*3+2]+0.5;
#endif
mData->SetPoint(i, p);
if (mZ == -1) mZ = p[2];
if (p[2] != mZ) {
if (std::fabs(p[2] - mZ) > mTolerance) {
DD(i);
DD(p[2]);
DD(mZ);
std::cout << "ERROR ! contour not in the same slice" << std::endl;
assert(p[2] == mZ);
//std::cout << "ERROR ! contour not in the same slice" << std::endl;
//assert(p[2] == mZ);
FATAL("ERROR ! contour not in the same slice");
}
}

Expand Down Expand Up @@ -202,7 +198,10 @@ bool clitk::DicomRT_Contour::Read(gdcm::SQItem * item)

// Read values [Contour Data]
std::vector<float> points = parse_string<float>(item->GetEntryValue(0x3006,0x0050),'\\');
assert(points.size() == static_cast<unsigned int>(mNbOfPoints)*3);
//assert(points.size() == static_cast<unsigned int>(mNbOfPoints)*3);
if (points.size() != static_cast<unsigned int>(mNbOfPoints)*3) {
FATAL("The number of contour points is inconsistent with the number of triplets defining the contour");
}

// Organize values
mData = vtkSmartPointer<vtkPoints>::New();
Expand All @@ -212,19 +211,16 @@ bool clitk::DicomRT_Contour::Read(gdcm::SQItem * item)
double p[3];
p[0] = points[i*3];
p[1] = points[i*3+1];
#if VTK_MAJOR_VERSION <= 5
p[2] = points[i*3+2];
#else
p[2] = points[i*3+2]+0.5;
#endif
mData->SetPoint(i, p);
if (mZ == -1) mZ = p[2];
if (p[2] != mZ) {
if (std::fabs(p[2] - mZ) > mTolerance) {
DD(i);
DD(p[2]);
DD(mZ);
std::cout << "ERROR ! contour not in the same slice" << std::endl;
assert(p[2] == mZ);
//std::cout << "ERROR ! contour not in the same slice" << std::endl;
//assert(p[2] == mZ);
FATAL("ERROR ! contour not in the same slice");
}
}

Expand Down Expand Up @@ -259,8 +255,17 @@ void clitk::DicomRT_Contour::SetTransformMatrix(vtkMatrix4x4* matrix)
mTransformMatrix = matrix;
}
//--------------------------------------------------------------------


//--------------------------------------------------------------------
double clitk::DicomRT_Contour::GetTolerance()
{
return mTolerance;
}
//--------------------------------------------------------------------
void clitk::DicomRT_Contour::SetTolerance(double tol)
{
mTolerance = tol;
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
void clitk::DicomRT_Contour::ComputeMeshFromDataPoints()
{
Expand All @@ -271,10 +276,10 @@ void clitk::DicomRT_Contour::ComputeMeshFromDataPoints()
mMesh->SetPoints(mPoints);
vtkIdType ids[2];
for (unsigned int idx=0 ; idx<mNbOfPoints ; idx++) {
double pointIn[4];
for (unsigned int j=0 ; j<3; ++j)
pointIn[j] = mData->GetPoint(idx)[j];
pointIn[3] = 1.0;
//double pointIn[4];
//for (unsigned int j=0 ; j<3; ++j)
// pointIn[j] = mData->GetPoint(idx)[j];
//pointIn[3] = 1.0;
/*double pointOut[4];
mTransformMatrix->MultiplyPoint(pointIn, pointOut);
std::cout << pointOut[0] << " " << pointOut[1] << " " << pointOut[2] << " " << pointOut[3] << std::endl;
Expand Down
Loading