stream << "# nbVal = " << nb_value << endl;
stream << "######################" << endl;
- const double* buffer = static_cast<const double*>(abstract_buffer);
- for (unsigned long kk=0; kk<nb_value; kk++) {
- stream << buffer[kk] << endl;
+ if(this->GetComponentType()==itk::ImageIOBase::UCHAR) {
+ const unsigned char* buffer = static_cast<const unsigned char*>(abstract_buffer);
+ for (unsigned long kk=0; kk<nb_value; kk++)
+ stream << buffer[kk] << endl;
+ } else if(this->GetComponentType()==itk::ImageIOBase::CHAR) {
+ const char* buffer = static_cast<const char*>(abstract_buffer);
+ for (unsigned long kk=0; kk<nb_value; kk++)
+ stream << buffer[kk] << endl;
+ } else if(this->GetComponentType()==itk::ImageIOBase::USHORT) {
+ const unsigned short* buffer = static_cast<const unsigned short*>(abstract_buffer);
+ for (unsigned long kk=0; kk<nb_value; kk++)
+ stream << buffer[kk] << endl;
+ } else if(this->GetComponentType()==itk::ImageIOBase::SHORT) {
+ const short* buffer = static_cast<const short*>(abstract_buffer);
+ for (unsigned long kk=0; kk<nb_value; kk++)
+ stream << buffer[kk] << endl;
+ } else if(this->GetComponentType()==itk::ImageIOBase::UINT) {
+ const unsigned int* buffer = static_cast<const unsigned int*>(abstract_buffer);
+ for (unsigned long kk=0; kk<nb_value; kk++)
+ stream << buffer[kk] << endl;
+ } else if(this->GetComponentType()==itk::ImageIOBase::INT) {
+ const int* buffer = static_cast<const int*>(abstract_buffer);
+ for (unsigned long kk=0; kk<nb_value; kk++)
+ stream << buffer[kk] << endl;
+ } else if(this->GetComponentType()==itk::ImageIOBase::ULONG) {
+ const unsigned long* buffer = static_cast<const unsigned long*>(abstract_buffer);
+ for (unsigned long kk=0; kk<nb_value; kk++)
+ stream << buffer[kk] << endl;
+ } else if(this->GetComponentType()==itk::ImageIOBase::LONG) {
+ const long* buffer = static_cast<const long*>(abstract_buffer);
+ for (unsigned long kk=0; kk<nb_value; kk++)
+ stream << buffer[kk] << endl;
+ } else if(this->GetComponentType()==itk::ImageIOBase::FLOAT) {
+ const float* buffer = static_cast<const float*>(abstract_buffer);
+ for (unsigned long kk=0; kk<nb_value; kk++)
+ stream << buffer[kk] << endl;
+ } else if(this->GetComponentType()==itk::ImageIOBase::DOUBLE) {
+ const double* buffer = static_cast<const double*>(abstract_buffer);
+ for (unsigned long kk=0; kk<nb_value; kk++)
+ stream << buffer[kk] << endl;
+ } else {
+ itkGenericExceptionMacro(<< "Unhandled pixel type: " << this->GetComponentTypeAsString(this->GetComponentType()));
+ return;
}
FILE* handle = fopen(m_FileName.c_str(),"w");
}
fwrite(stream.str().c_str(),1,stream.str().size(),handle);
-
fclose(handle);
}
typedef GateAsciiImageIO Self;
typedef itk::ImageIOBase Superclass;
typedef itk::SmartPointer<Self> Pointer;
- typedef signed short int PixelType;
struct GateAsciiHeader {
double matrix_size[3];
DEF_SetNextOutput_And_GetInput(float, 3);
DEF_SetNextOutput_And_GetInput(double, 3);
+/*
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned char, 2, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned char, 2, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned char, 2, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned char, 3, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned char, 3, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned char, 3, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned char, 4, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned char, 4, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned char, 4, 4);
+
+DEF_SetNextOutput_And_GetInput_WithCompo(char, 2, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(char, 2, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(char, 2, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(char, 3, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(char, 3, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(char, 3, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(char, 4, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(char, 4, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(char, 4, 4);
+
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned short, 2, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned short, 2, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned short, 2, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned short, 3, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned short, 3, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned short, 3, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned short, 4, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned short, 4, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned short, 4, 4);
+
+DEF_SetNextOutput_And_GetInput_WithCompo(short, 2, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(short, 2, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(short, 2, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(short, 3, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(short, 3, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(short, 3, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(short, 4, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(short, 4, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(short, 4, 4);
+
+DEF_SetNextOutput_And_GetInput_WithCompo(int, 2, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(int, 2, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(int, 2, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(int, 3, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(int, 3, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(int, 3, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(int, 4, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(int, 4, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(int, 4, 4);
+*/
+
DEF_SetNextOutput_And_GetInput_WithCompo(float, 2, 2);
DEF_SetNextOutput_And_GetInput_WithCompo(float, 2, 3);
DEF_SetNextOutput_And_GetInput_WithCompo(float, 2, 4);
// clitk include
#include "clitkCommon.h"
#include "clitkMemoryUsage.h"
-#include <unistd.h>
+#ifndef _WIN32
+# include <unistd.h>
+#endif
void clitk::PrintMemory(bool verbose, std::string s)
{
#include <math.h>
#include <stdlib.h>
#include <limits.h>
-#include <unistd.h>
+#ifndef _WIN32
+# include <unistd.h>
+#endif
#if !defined(unix) && !defined(__APPLE__)
#include <io.h>
#endif
void BeforeThreadedGenerateData(void );
// Threaded Generate Data
+#if ITK_VERSION_MAJOR >= 4
+ void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, itk::ThreadIdType threadId );
+#else
void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, int threadId );
+#endif
//------------------------------------------------
template <class InputImageType, class OutputImageType>
void
BackProjectImageFilter<InputImageType, OutputImageType>
+#if ITK_VERSION_MAJOR >= 4
+ ::ThreadedGenerateData( const OutputImageRegionType & outputRegionForThread, itk::ThreadIdType threadId )
+#else
::ThreadedGenerateData( const OutputImageRegionType & outputRegionForThread, int threadId )
+#endif
{
//Projection pointer
InputImageConstPointer inputPtr=this->GetInput();
const OutputImageRegionType &srcRegion);
- void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
- int threadId );
+#if ITK_VERSION_MAJOR >= 4
+ void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId );
+#else
+ void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, int threadId );
+#endif
+
InputImageRegionType m_ExtractionRegion;
OutputImageRegionType m_OutputImageRegion;
template <class TInputImage, class TOutputImage>
void
ExtractImageFilter<TInputImage,TOutputImage>
-::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
- int threadId)
+#if ITK_VERSION_MAJOR >= 4
+::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId)
+#else
+::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, int threadId)
+#endif
{
itkDebugMacro(<<"Actually executing");
+++ /dev/null
-/*=========================================================================
- Program: vv http://www.creatis.insa-lyon.fr/rio/vv
-
- Authors belong to:
- - University of LYON http://www.universite-lyon.fr/
- - Léon Bérard cancer center http://www.centreleonberard.fr
- - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the copyright notices for more information.
-
- It is distributed under dual licence
-
- - BSD See included LICENSE.txt file
- - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================**/
-#ifndef __clitkExtractImageFilter_h
-#define __clitkExtractImageFilter_h
-#include "itkImageToImageFilter.h"
-#include "itkSmartPointer.h"
-#include "itkExtractImageFilterRegionCopier.h"
-
-namespace clitk
-{
-
-template <class TInputImage, class TOutputImage>
-class ITK_EXPORT ExtractImageFilter:
- public itk::ImageToImageFilter<TInputImage,TOutputImage>
-{
-public:
- /** Standard class typedefs. */
- typedef ExtractImageFilter Self;
- typedef itk::ImageToImageFilter<TInputImage,TOutputImage> Superclass;
- typedef itk::SmartPointer<Self> Pointer;
- typedef itk::SmartPointer<const Self> ConstPointer;
-
- /** Method for creation through the object factory. */
- itkNewMacro(Self);
-
- /** Run-time type information (and related methods). */
- itkTypeMacro(ExtractImageFilter, ImageToImageFilter);
-
- /** Image type information. */
- typedef TInputImage InputImageType;
- typedef TOutputImage OutputImageType;
-
- /** Typedef to describe the output and input image region types. */
- typedef typename TOutputImage::RegionType OutputImageRegionType;
- typedef typename TInputImage::RegionType InputImageRegionType;
-
- /** Typedef to describe the type of pixel. */
- typedef typename TOutputImage::PixelType OutputImagePixelType;
- typedef typename TInputImage::PixelType InputImagePixelType;
-
- /** Typedef to describe the output and input image index and size types. */
- typedef typename TOutputImage::IndexType OutputImageIndexType;
- typedef typename TInputImage::IndexType InputImageIndexType;
- typedef typename TOutputImage::SizeType OutputImageSizeType;
- typedef typename TInputImage::SizeType InputImageSizeType;
-
- /** ImageDimension enumeration */
- itkStaticConstMacro(InputImageDimension, unsigned int,
- TInputImage::ImageDimension);
- itkStaticConstMacro(OutputImageDimension, unsigned int,
- TOutputImage::ImageDimension);
-
- typedef itk::ImageToImageFilterDetail::ExtractImageFilterRegionCopier<
- itkGetStaticConstMacro(InputImageDimension),
- itkGetStaticConstMacro(OutputImageDimension)> ExtractImageFilterRegionCopierType;
-
- void SetExtractionRegion(InputImageRegionType extractRegion);
- itkGetMacro(ExtractionRegion, InputImageRegionType);
-
-#ifdef ITK_USE_CONCEPT_CHECKING
- /** Begin concept checking */
- itkConceptMacro(InputCovertibleToOutputCheck,
- (itk::Concept::Convertible<InputImagePixelType, OutputImagePixelType>));
- /** End concept checking */
-#endif
-
-protected:
- ExtractImageFilter();
- ~ExtractImageFilter() {};
- void PrintSelf(std::ostream& os, itk::Indent indent) const;
-
-
- virtual void GenerateOutputInformation();
-
-
- virtual void CallCopyOutputRegionToInputRegion(InputImageRegionType &destRegion,
- const OutputImageRegionType &srcRegion);
-
-
- void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
- int threadId );
- InputImageRegionType m_ExtractionRegion;
- OutputImageRegionType m_OutputImageRegion;
-
-private:
- ExtractImageFilter(const Self&); //purposely not implemented
- void operator=(const Self&); //purposely not implemented
-
-};
-
-
-} // end namespace itk
-
-#ifndef ITK_MANUAL_INSTANTIATION
-#include "clitkExtractImageFilter.txx"
-#endif
-
-#endif
+++ /dev/null
-/*=========================================================================
- Program: vv http://www.creatis.insa-lyon.fr/rio/vv
-
- Authors belong to:
- - University of LYON http://www.universite-lyon.fr/
- - Léon Bérard cancer center http://www.centreleonberard.fr
- - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the copyright notices for more information.
-
- It is distributed under dual licence
-
- - BSD See included LICENSE.txt file
- - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================**/
-#ifndef _clitkExtractImageFilter_txx
-#define _clitkExtractImageFilter_txx
-#include "clitkExtractImageFilter.h"
-#include "itkImageRegionIterator.h"
-#include "itkImageRegionConstIterator.h"
-#include "itkObjectFactory.h"
-#include "itkExtractImageFilterRegionCopier.h"
-#include "itkProgressReporter.h"
-
-
-namespace clitk
-{
-
-/**
- *
- */
-template <class TInputImage, class TOutputImage>
-ExtractImageFilter<TInputImage,TOutputImage>
-::ExtractImageFilter()
-{
-}
-
-
-/**
- *
- */
-template <class TInputImage, class TOutputImage>
-void
-ExtractImageFilter<TInputImage,TOutputImage>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
- Superclass::PrintSelf(os,indent);
-
- os << indent << "ExtractionRegion: " << m_ExtractionRegion << std::endl;
- os << indent << "OutputImageRegion: " << m_OutputImageRegion << std::endl;
-}
-
-
-template<class TInputImage, class TOutputImage>
-void
-ExtractImageFilter<TInputImage,TOutputImage>
-::CallCopyOutputRegionToInputRegion(InputImageRegionType &destRegion,
- const OutputImageRegionType &srcRegion)
-{
- ExtractImageFilterRegionCopierType extractImageRegionCopier;
- extractImageRegionCopier(destRegion, srcRegion, m_ExtractionRegion);
-}
-
-
-template <class TInputImage, class TOutputImage>
-void
-ExtractImageFilter<TInputImage,TOutputImage>
-::SetExtractionRegion(InputImageRegionType extractRegion)
-{
- m_ExtractionRegion = extractRegion;
-
- unsigned int nonzeroSizeCount = 0;
- InputImageSizeType inputSize = extractRegion.GetSize();
- OutputImageSizeType outputSize;
- OutputImageIndexType outputIndex;
-
- /**
- * check to see if the number of non-zero entries in the extraction region
- * matches the number of dimensions in the output image.
- **/
- for (unsigned int i = 0; i < InputImageDimension; ++i)
- {
- if (inputSize[i])
- {
- outputSize[nonzeroSizeCount] = inputSize[i];
- outputIndex[nonzeroSizeCount] = extractRegion.GetIndex()[i];
- nonzeroSizeCount++;
- }
- }
-
- if (nonzeroSizeCount != OutputImageDimension)
- {
- itkExceptionMacro("Extraction Region not consistent with output image");
- }
-
- m_OutputImageRegion.SetSize(outputSize);
- m_OutputImageRegion.SetIndex(outputIndex);
- this->Modified();
-}
-
-
-
-/**
- * ExtractImageFilter can produce an image which is a different resolution
- * than its input image. As such, ExtractImageFilter needs to provide an
- * implementation for GenerateOutputInformation() in order to inform
- * the pipeline execution model. The original documentation of this
- * method is below.
- *
- * \sa ProcessObject::GenerateOutputInformaton()
- */
-template <class TInputImage, class TOutputImage>
-void
-ExtractImageFilter<TInputImage,TOutputImage>
-::GenerateOutputInformation()
-{
- // do not call the superclass' implementation of this method since
- // this filter allows the input and the output to be of different dimensions
-
- // get pointers to the input and output
- typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
- typename Superclass::InputImageConstPointer inputPtr = this->GetInput();
-
- if ( !outputPtr || !inputPtr)
- {
- return;
- }
-
- // Set the output image size to the same value as the extraction region.
- outputPtr->SetLargestPossibleRegion( m_OutputImageRegion );
-
- // Set the output spacing and origin
- const itk::ImageBase<InputImageDimension> *phyData;
-
- phyData
- = dynamic_cast<const itk::ImageBase<InputImageDimension>*>(this->GetInput());
-
- if (phyData)
- {
- // Copy what we can from the image from spacing and origin of the input
- // This logic needs to be augmented with logic that select which
- // dimensions to copy
-
- unsigned int i;
- const typename InputImageType::SpacingType&
- inputSpacing = inputPtr->GetSpacing();
- const typename InputImageType::DirectionType&
- inputDirection = inputPtr->GetDirection();
- const typename InputImageType::PointType&
- inputOrigin = inputPtr->GetOrigin();
-
- typename OutputImageType::SpacingType outputSpacing;
- typename OutputImageType::DirectionType outputDirection;
- typename OutputImageType::PointType outputOrigin;
-
- if ( static_cast<unsigned int>(OutputImageDimension) >
- static_cast<unsigned int>(InputImageDimension ) )
- {
- // copy the input to the output and fill the rest of the
- // output with zeros.
- for (i=0; i < InputImageDimension; ++i)
- {
- outputSpacing[i] = inputSpacing[i];
- outputOrigin[i] = inputOrigin[i];
- for (unsigned int dim = 0; dim < InputImageDimension; ++dim)
- {
- outputDirection[i][dim] = inputDirection[i][dim];
- }
- }
- for (; i < OutputImageDimension; ++i)
- {
- outputSpacing[i] = 1.0;
- outputOrigin[i] = 0.0;
- for (unsigned int dim = 0; dim < InputImageDimension; ++dim)
- {
- outputDirection[i][dim] = 0.0;
- }
- outputDirection[i][i] = 1.0;
- }
- }
- else
- {
- // copy the non-collapsed part of the input spacing and origing to the output
- int nonZeroCount = 0;
- for (i=0; i < InputImageDimension; ++i)
- {
- if (m_ExtractionRegion.GetSize()[i])
- {
- outputSpacing[nonZeroCount] = inputSpacing[i];
- outputOrigin[nonZeroCount] = inputOrigin[i];
- int nonZeroCount2 = 0;
- for (unsigned int dim = 0; dim < InputImageDimension; ++dim)
- {
- if (m_ExtractionRegion.GetSize()[dim])
- {
- outputDirection[nonZeroCount][nonZeroCount2] =
- inputDirection[i][dim];
- ++nonZeroCount2;
- }
- }
- nonZeroCount++;
- }
- }
- }
-
- // set the spacing and origin
- outputPtr->SetSpacing( outputSpacing );
- outputPtr->SetDirection( outputDirection );
- outputPtr->SetOrigin( outputOrigin );
- outputPtr->SetNumberOfComponentsPerPixel(inputPtr->GetNumberOfComponentsPerPixel() );
- }
- else
- {
- // pointer could not be cast back down
- itkExceptionMacro(<< "itk::ExtractImageFilter::GenerateOutputInformation "
- << "cannot cast input to "
- << typeid(itk::ImageBase<InputImageDimension>*).name() );
- }
-}
-
-/**
- * ExtractImageFilter can be implemented as a multithreaded filter.
- * Therefore, this implementation provides a ThreadedGenerateData()
- * routine which is called for each processing thread. The output
- * image data is allocated automatically by the superclass prior to
- * calling ThreadedGenerateData(). ThreadedGenerateData can only
- * write to the portion of the output image specified by the
- * parameter "outputRegionForThread"
- *
- * \sa ImageToImageFilter::ThreadedGenerateData(),
- * ImageToImageFilter::GenerateData()
- */
-template <class TInputImage, class TOutputImage>
-void
-ExtractImageFilter<TInputImage,TOutputImage>
-::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
- int threadId)
-{
- itkDebugMacro(<<"Actually executing");
-
- // Get the input and output pointers
- typename Superclass::InputImageConstPointer inputPtr = this->GetInput();
- typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
-
- // support progress methods/callbacks
- itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
-
- // Define the portion of the input to walk for this thread
- InputImageRegionType inputRegionForThread;
- this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread);
-
- // Define the iterators.
- typedef itk::ImageRegionIterator<TOutputImage> OutputIterator;
- typedef itk::ImageRegionConstIterator<TInputImage> InputIterator;
-
- OutputIterator outIt(outputPtr, outputRegionForThread);
- InputIterator inIt(inputPtr, inputRegionForThread);
-
- // walk the output region, and sample the input image
- while( !outIt.IsAtEnd() )
- {
- // copy the input pixel to the output
- outIt.Set( static_cast<OutputImagePixelType>(inIt.Get()));
- ++outIt;
- ++inIt;
- progress.CompletedPixel();
- }
-}
-
-} // end namespace clitk
-
-#endif
${CLITK_SOURCE_DIR}/scripts/calculate_contour_stats.sh
${CLITK_SOURCE_DIR}/scripts/midp_common.sh
${CLITK_SOURCE_DIR}/scripts/registration.sh
+ ${CLITK_SOURCE_DIR}/scripts/compress_mhd.sh
${CLITK_SOURCE_DIR}/scripts/create_midP.sh
${CLITK_SOURCE_DIR}/scripts/create_midP-2.0.sh
${CLITK_SOURCE_DIR}/scripts/create_mhd_4D.sh
#! /bin/bash +x
-select_contour_gui()
-{
- local roi_list=$@
- roi=`zenity --list --title="Available Contours" --column="Please choose a contour:" $roi_list`
- case $? in
- 0)
- if [ -z $roi ]
- then
- zenity --warning --text="You must choose one contour."
- select_contour $roi_list
- else
- rtstruct_roi_name=$roi
- fi;;
- 1)
- if zenity --question --text="Do you really wish to quit?"
- then
- exit
- else
- select_contour $roi_list
- fi;;
- -1)
- zenity --error --text="Unexpected error. Please relaunch the application."
- exit;;
- esac
-}
+source `dirname $0`/midp_common.sh
-select_contour()
-{
- local roi_list=$@
- echo "Available Contours:"
- for r in $roi_list; do
- echo $r
- done
-
- echo "Please choose a contour number:"
- read rtstruct_roi_number
-}
-
-select_roi()
-{
- rtstruct_roi_name_list=( `clitkDicomInfo ${rtstruct_file} | grep "3006|0026" | cut -d '[' -f 4 | sed 's/| V 3006|0026[LO] [ROI Name] \|]//'` )
- rtstruct_roi_number_list=( `clitkDicomInfo ${rtstruct_file} | grep "3006|0022" | cut -d '[' -f 4 | sed 's/| V 3006|0026[LO] [ROI Number] \|]//'` )
- rtstruct_roi_list=( )
- for i in $(seq 0 1 $(( ${#rtstruct_roi_name_list[@]} - 1 ))); do
- rtstruct_roi_list[$i]=${rtstruct_roi_number_list[$i]}:${rtstruct_roi_name_list[$i]}
- done
-
- if [ $gui_mode = 1 ]; then
- select_contour_gui ${rtstruct_roi_list[@]}
- rtstruct_roi=`echo ${rtstruct_roi_name} | cut -d ':' -f 1`
- rtstruct_roi_name=`echo ${rtstruct_roi_name} | cut -d ':' -f 2`
- else
- select_contour ${rtstruct_roi_list[@]}
- rtstruct_roi=$rtstruct_roi_number
- rtstruct_roi_name=${rtstruct_roi_name_list[$(( $rtstruct_roi_number - 1))]}
- fi
-}
############# main
if echo $* | grep "\-h"; then
- echo Usage: calculate_motion_amplitude.sh { RTSTRUCT_FILE REFERENCE_IMAGE | --gui }
-
+ echo Usage: calculate_motion_amplitude.sh { REFERENCE_IMAGE RTSTRUCT_FILE [ RTSTRUCT_ROI | --gui ] } | --gui
+ echo " RTSTRUCT_REF_IMAGE: mhd of the reference image used in the contour delineation"
+ echo " RTSTRUCT_FILE: dicom with contours"
+ echo " RTSTRUCT_ROI: number of the contour whose motion to analyze"
+ echo " --gui: use GUI to select files"
exit 0
fi
-rtstruct_roi=0
+rtstruct_roi=
if echo $* | grep "\-\-gui" > /dev/null 2>&1; then
- if [ $# != 1 ]; then
+ gui_mode=1
+ if [ $# = 1 ]; then
+ rtstruct_ref_image=`zenity --file-selection --title="Select Reference Image."`
+ rtstruct_file=`zenity --file-selection --title="Select RT Struct file."`
+ select_roi
+ elif [ $# = 3 ]; then
+ rtstruct_ref_image=$1
+ rtstruct_file=$2
+ select_roi
+ else
echo Invalid arguments. Type \'`basename $0` -h\' for help
exit -1
fi
- gui_mode=1
- rtstruct_file=`zenity --file-selection --title="Select RT Struct file."`
- select_roi
- rtstruct_ref_image=`zenity --file-selection --title="Select Reference Image."`
else
- if [ $# != 2 ]; then
+ gui_mode=0
+ rtstruct_ref_image=$1
+ rtstruct_file=$2
+ if [ $# = 2 ]; then
+ select_roi
+ elif [ $# = 3 ]; then
+ rtstruct_roi=$3
+ rtstruct_roi_name=$rtstruct_roi
+ else
echo Invalid arguments. Type \'`basename $0` -h\' for help
exit -1
fi
- gui_mode=0
- rtstruct_file=$1
- rtstruct_ref_image=$2
- select_roi
fi
#! /bin/bash +x
+source `dirname $0`/midp_common.sh
+
+
+calculate_motion()
+{
+ # calculate motion amplitudes along the 3 image axes
+ rm /tmp/result.txt 2> /dev/null
+ dir=( "\"left-right\"" "\"anterior-posterior\"" "\"cranio-caudal\"" )
+ pct=( 0 33 67 )
+ for i in 0 1 2; do
+ if [ $gui_mode = 1 ]; then
+ echo "${pct[$i]}"; echo "# Calculating motion along ${dir[$i]} direction.."
+ else
+ echo "Calculating motion along ${dir[$i]} direction.."
+ fi
+
+ echo "Motion along ${dir[$i]} direction" >> /tmp/result.txt
+ clitkImageStatistics -i ${vector_file} -m ${roi_mask2} -c $i --verbose 2> /dev/null | tail -n 8 | head -n 6 >> /tmp/result.txt
+ min=`tail -n 2 /tmp/result.txt | head -n 1 | cut -f 2 -d ':'`
+ max=`tail -n 1 /tmp/result.txt | cut -f 2 -d ':'`
+ amp=`echo $max-$min | bc`
+
+ echo "Amplitude: $amp" >> /tmp/result.txt
+ echo "" >> /tmp/result.txt
+ done
+}
+
############# main
if echo $* | grep "\-h"; then
- echo Usage: calculate_motion_amplitude.sh VECTOR_FILE RTSTRUCT_FILE RTSTRUCT_ROI_NUMBER RTSTRUCT_REF_IMAGE
+ echo "Usage: calculate_motion_amplitude.sh { VECTOR_FILE RTSTRUCT_REF_IMAGE RTSTRUCT_FILE [ RTSTRUCT_ROI_NUMBER | --gui ] } | --gui "
echo " VECTOR_FILE: mhd of the vector field from where to extract motion information (may also be 4D)"
+ echo " RTSTRUCT_REF_IMAGE: mhd of the reference image used in the contour delineation"
echo " RTSTRUCT_FILE: dicom with contours"
echo " RTSTRUCT_ROI: number of the contour whose motion to analyze"
- echo " RTSTRUCT_REF_IMAGE: mhd of the reference image used in the contour delineation"
-
+ echo " --gui: use GUI to select files"
exit 0
fi
-if [ $# != 4 ]; then
- echo Invalid arguments. Type \'`basename $0` -h\' for help
- exit -1
+if echo $* | grep "\-\-gui" > /dev/null 2>&1; then
+ gui_mode=1
+ if [ $# = 1 ]; then
+ vector_file=`zenity --file-selection --title="Select 4D Vector Field file."`
+ rtstruct_ref_image=`zenity --file-selection --title="Select Reference Image."`
+ rtstruct_file=`zenity --file-selection --title="Select RT Struct file."`
+ select_roi
+ elif [ $# = 4 ]; then
+ vector_file=$1
+ rtstruct_ref_image=$2
+ rtstruct_file=$3
+ select_roi
+ else
+ echo Invalid arguments. Type \'`basename $0` -h\' for help
+ exit -1
+ fi
+else
+ gui_mode=0
+ vector_file=$1
+ rtstruct_ref_image=$2
+ rtstruct_file=$3
+ if [ $# = 4 ]; then
+ rtstruct_roi=$4
+ rtstruct_roi_name=$rtstruct_roi
+ elif [ $# = 3 ]; then
+ select_roi
+ else
+ echo Invalid arguments. Type \'`basename $0` -h\' for help
+ exit -1
+ fi
fi
-vector_file=$1
-rtstruct_file=$2
-rtstruct_roi=$3
-rtstruct_ref_image=$4
-
if ! cat $vector_file | grep -q "Channels = 3"; then
echo Vector file must have 3 channels.
exit -2
# create ROI mask from rtstruct
roi_mask=roi_${rtstruct_roi}.mhd
-clitkDicomRTStruct2BinaryImage -i ${rtstruct_file} -o ${roi_mask} -j ${rtstruct_ref_image} -r ${rtstruct_roi} 2> /tmp/err.txt
+clitkDicomRTStruct2Image -i ${rtstruct_file} -o ${roi_mask} -j ${rtstruct_ref_image} -r ${rtstruct_roi} 2> /tmp/err.txt
if cat /tmp/err.txt | grep -q "No ROI"; then
echo Invalid contour number.
exit -3
roi_mask2=resampled_${roi_mask}
clitkResampleImage -i ${roi_mask} -o ${roi_mask2} --like ${vector_file}
-# calculate motion amplitudes along the 3 image axes
-dir=( sagittal coronal axial )
-for i in 0 1 2; do
- echo Motion along ${dir[$i]} direction
- clitkImageStatistics -i ${vector_file} -m ${roi_mask2} -c $i --verbose 2> /dev/null | tail -n 8 | head -n 6 > /tmp/res.txt
- min=`tail -n 2 /tmp/res.txt | head -n 1 | cut -f 2 -d ':'`
- max=`tail -n 1 /tmp/res.txt | cut -f 2 -d ':'`
- amp=`echo $max-$min | bc`
- cat /tmp/res.txt
- echo "Amplitude: $amp"
- echo
-done
+if [ $gui_mode = 1 ]; then
+ calculate_motion | zenity --progress --auto-close --percentage=0 --text=""
+else
+ calculate_motion
+fi
+
+if [ $gui_mode = 1 ]; then
+ cat /tmp/result.txt | zenity --text-info --title "Restuls for \"${rtstruct_roi_name}\""
+else
+ echo "Restuls for \"${rtstruct_roi_name}\""
+ cat /tmp/result.txt
+fi
rm `basename $roi_mask .mhd`.{mhd,raw}
rm `basename $roi_mask2 .mhd`.{mhd,raw}
rm /tmp/err.txt
-rm /tmp/res.txt
+rm /tmp/result.txt
--- /dev/null
+#! /bin/bash
+
+compress_file()
+{
+ local f=$1
+ if [ "$verbose" = "1" ]; then
+ echo "Compressing $f..."
+ fi
+
+ local msg=`clitkImageConvert -i $f -o $f -c`
+ if [ -z "$msg" ]; then
+ raw=`echo $f | sed 's/\.mhd/\.raw/'`
+ if test -e $raw; then
+ rm $raw
+ fi
+ fi
+}
+
+compress_directory()
+{
+ local input=$1
+
+ files=$(find $input -name "*.mhd" | sort)
+ for f in $files; do
+ if ! grep -iq 'LIST' $f; then
+ # process all except 4D files
+ compress_file $f
+ else
+ # process only 4D files (just update pointers to new zraw files)
+ # assumes each .RAW in the list has a corresponding .MHD, which
+ # must be compressed separately
+ sed -i 's/\.raw/\.zraw/g' $f
+ if grep -q "CompressedData" $f; then
+ sed -i 's/CompressedData.*/CompressedData = True/' $f
+ else
+ tmp=/tmp/$RANDOM.mhd
+ echo "CompressedData = True" > $tmp
+ cat $f >> $tmp
+ mv $tmp $f
+ fi
+ fi
+ done
+}
+
+# main program
+
+if [ $# -lt 1 -o $# -gt 2 ]; then
+ echo "Invalid params. `basename $0` [-h | --help] for help" 1>&2
+ exit -1
+fi
+
+if [ -n "`echo $@ | grep '\-h\|--help'`" ]; then
+ echo "Usage: `basename $0` {FILE | DIRECTORY | -h | --help | -v}"
+ exit 0
+fi
+
+if [ -n "`echo $@ | grep '\-v'`" ]; then
+ echo Verbose mode : ON
+ verbose=1
+fi
+
+input=$1
+if test -d $input; then
+ compress_directory $input
+elif test -f $input; then
+ compress_file $input
+else
+ echo "Unknow input file type." 1>&2
+fi
-#!/bin/sh
+#!/bin/sh +x
write_mhd_4D()
/DimSize/ s/.*/& $nbph/
s/ElementDataFile = .*/ElementDataFile = LIST/" > "$1/$file_name_4D"
- for ph in $listph
+ for ph in ${listph[@]}
do
ph=`basename $ph`
echo "$ph" >> "$1/$file_name_4D"
done
+ echo $1/$file_name_4D
}
#################################################
list_phase_file=`find $1 -maxdepth 1 -iname "*[0-9]*.mhd"`
for phase_file in $list_phase_file
do
- phase_file_name=`basename $phase_file`
- if [[ ! -z `echo "$phase_file_name" | grep "__[0-9]"` ]]
+ if grep -q "NDims = 4" $phase_file 2> /dev/null
then
- prefix=`echo $phase_file_name | sed "s/__[0-9].*/__/"`
- else
- if [[ ! -z `echo "$phase_file_name" | grep "[0-9]-.*\]"` ]]
- then
- if [[ ! -z `echo "$phase_file_name" | grep "[0-9][0-9]-.*\]"` ]]
- then
- prefix=`echo $phase_file_name | sed "s/[0-9][0-9]-.*//"`
- else
- prefix=`echo $phase_file_name | sed "s/[0-9]-.*//"`
- fi
- else
- prefix="NONE"
- fi
+ #echo $phase_file is 4D
+ continue;
+ fi;
+
+ phase_file_name=`basename $phase_file .mhd`
+# if [[ ! -z `echo "$phase_file_name" | grep "__[0-9]"` ]]
+# then
+# prefix=`echo $phase_file_name | sed "s/__[0-9].*/__/"`
+# else
+# if [[ ! -z `echo "$phase_file_name" | grep "[0-9]-.*\]"` ]]
+# then
+# if [[ ! -z `echo "$phase_file_name" | grep "[0-9][0-9]-.*\]"` ]]
+# then
+# prefix=`echo $phase_file_name | sed "s/[0-9][0-9]-.*//"`
+# else
+# prefix=`echo $phase_file_name | sed "s/[0-9]-.*//"`
+# fi
+# else
+# prefix="NONE"
+# fi
+# fi
+
+ # preffix: grep sequence of characters followed by sequence of numbers and remove sequence of numbers
+ # prefix=`echo $phase_file_name | grep -o "\(^[[:alpha:][:punct:]]*\)\([[:digit:]\.\_\-]\+\)" | sed 's/\(^[[:alpha:][:punct:]]*\)\([[:digit:]\.\_\-]\+\)/\1/'`
+ prefix=`echo $phase_file_name | grep -o "\(^[[:alpha:][:punct:]]*\)\([[:digit:]]\+\)\([\.\_\-]*\)"`
+ prefix=`echo $prefix | sed 's/^\-\+//' | sed 's/\(^[[:alpha:][:punct:]]*\)\([[:digit:]]\+\)\([\.\_\-]*\)/\1/'`
+ if [[ -z $prefix ]]
+ then
+ prefix="NONE"
fi
- if [[ -z `echo "$list_prefix" | grep "$prefix"` ]]
+ # register new preffix if not yet done
+ if [[ -z `echo "$list_prefix" | grep -w -- "$prefix"` ]]
then
list_prefix="$list_prefix $prefix"
fi
list_phase_file_prefix=`find $1 -maxdepth 1 -iname "${prefix}[0-9]*.mhd"`
for phase_file_prefix in $list_phase_file_prefix
do
- phase_file_prefix_name=`basename $phase_file_prefix`
- if [[ ! -z `echo "$phase_file_prefix_name" | grep "__[0-9]"` ]]
+ if grep -q "NDims = 4" $phase_file_prefix 2> /dev/null
then
+ #echo $phase_file_prefix is 4D
+ continue;
+ fi;
+ phase_file_prefix_name=`basename $phase_file_prefix .mhd`
+# if [[ ! -z `echo "$phase_file_prefix_name" | grep "__[0-9]"` ]]
+# then
+# suffix="NONE"
+# else
+# if [[ ! -z `echo "$phase_file_prefix_name" | grep "[0-9]-.*\]"` ]]
+# then
+# suffix=`echo $phase_file_prefix_name | sed "s/.*[0-9]-//;s/_\.mhd//;s/\.mhd//"`
+# else
+# suffix="NONE"
+# fi
+# fi
+#
+
+ # suffix: grep sequence of numbers followed by sequence of characters and remove sequence of numbers
+ # suffix=`echo $phase_file_prefix_name | grep -o "\([[:digit:]\.\_\-]\+\)\([[:alpha:][:punct:]]*$\)" | sed 's/\([[:digit:]\.\_\-]\+\)\([[:alpha:][:punct:]]*$\)/\2/'`
+ suffix=`echo $phase_file_prefix_name | grep -o "\([\.\_\-]*\)\([[:digit:]]\+\)\([[:alpha:][:punct:]]*$\)"`
+ if ! echo $suffix | grep -qo "^\-\+"; then
+ suffix=`echo $suffix | sed 's/\([\.\_\-]*\)\([[:digit:]]\+\)\([[:alpha:][:punct:]]*$\)/\3/'`
+ fi
+ suffix=`echo $suffix | sed 's/[\.\_\-]\+$//'`
+ if [[ -z $suffix ]]
+ then
suffix="NONE"
- else
- if [[ ! -z `echo "$phase_file_prefix_name" | grep "[0-9]-.*\]"` ]]
- then
- suffix=`echo $phase_file_prefix_name | sed "s/.*[0-9]-//;s/_\.mhd//;s/\.mhd//"`
- else
- suffix="NONE"
- fi
fi
- if [[ -z `echo "$list_suffix" | grep "$suffix"` ]]
+ # register new suffix if not yet done
+ if [[ -z `echo "$list_suffix" | grep -w -- "$suffix"` ]]
then
list_suffix="$list_suffix $suffix"
fi
done
+
for suffix in $list_suffix
do
if [ "$suffix" = "NONE" ]
then
suffix=""
fi
- nbph=`find $1 -maxdepth 1 -iname "*${prefix}*[0-9]*${suffix}*.mhd" | wc -l`
- orig=`find $1 -maxdepth 1 -iname "*${prefix}*[0-9]*${suffix}*.mhd" | sort | head -n 1`
- listph=`find $1 -maxdepth 1 -iname "*${prefix}*[0-9]*${suffix}*.raw" | sort`
-
- file_name_4D="${prefix}4D${suffix}.mhd"
-
- write_mhd_4D $1
+ orig=`find $1 -maxdepth 1 -iname "${prefix}[0-9]*${suffix}*.mhd" | grep "${prefix}[[:digit:][:punct:]]\+${suffix}[\.\_\-]*.mhd" | sort | head -n 1`
+ listph=( `find $1 -maxdepth 1 -iname "${prefix}[0-9]*${suffix}*.*raw" | grep "${prefix}[[:digit:][:punct:]]\+${suffix}[\.\_\-]*.z*raw" | sort` )
+ nbph=${#listph[@]}
+
+ # only create 4D file if potential number of phases is > 1
+ if [ $nbph -gt 1 ]; then
+ file_name_4D="${prefix}4D${suffix}.mhd"
+ write_mhd_4D $1
+ fi
done
echo "$phase_file -> Resampling..."
clitkResampleImage -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/patient_$phase_nb.mhd --spacing $resample_spacing --interp $resample_algo
clitkResampleImage -i $mask_dir_tmp/patient_mask_$phase_nb.mhd -o $mask_dir_tmp/patient_mask_$phase_nb.mhd --spacing $resample_spacing --interp $resample_algo
- clitkResampleImage -i $mask_dir_tmp/lungs_$phase_nb.mhd -o $mask_dir_tmp/lungs_$phase_nb.mhd --like $mask_dir_tmp/patient_$phase_nb.mhd
- clitkResampleImage -i $mask_dir_tmp/bones_$phase_nb.mhd -o $mask_dir_tmp/bones_$phase_nb.mhd --like $mask_dir_tmp/patient_$phase_nb.mhd
+ if [ "$mask_type" != "patient" ]; then
+ clitkResampleImage -i $mask_dir_tmp/lungs_$phase_nb.mhd -o $mask_dir_tmp/lungs_$phase_nb.mhd --like $mask_dir_tmp/patient_$phase_nb.mhd
+ fi
+ if [ "$mask_type" == "mm" ]; then
+ clitkResampleImage -i $mask_dir_tmp/bones_$phase_nb.mhd -o $mask_dir_tmp/bones_$phase_nb.mhd --like $mask_dir_tmp/patient_$phase_nb.mhd
+ fi
}
compute_motion_mask()
FillingLevel=94
fi
- #clitkMotionMask -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/mm_$phase_nb.mhd --featureLungs $mask_dir_tmp/lungs_$phase_nb.mhd --upperThresholdLungs -400 --fillingLevel $FillingLevel --offsetDetect $MotionMaskOffsetDetect --pad --writeFeature=$mask_dir_tmp/feature_$phase_nb.mhd $MotionMaskExtra
clitkMotionMask -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/mm_$phase_nb.mhd --featureLungs $mask_dir_tmp/lungs_$phase_nb.mhd --upperThresholdLungs -400 --featureBones $mask_dir_tmp/bones_$phase_nb.mhd --fillingLevel $FillingLevel --offsetDetect $MotionMaskOffsetDetect --pad --writeFeature $mask_dir_tmp/feature_$phase_nb.mhd $MotionMaskExtra
#--monitor=$mask_dir_tmp/monitor_$phase_nb.mhd
}
create_banded_mask $mask_dir_tmp/outside_$phase_nb.mhd $mask_dir_tmp/${mask_type}_outside_$phase_nb.mhd $mask_dir_tmp/banded_outside_$phase_nb.mhd $mask_dir_tmp/banded_mask_outside_$phase_nb.mhd 4
}
-create_registration_motion_masks()
+mm_preprocessing()
{
- # extract inside and outside regions from the patient image,
- # using the motion mask computed previously
- echo "$phase_file -> Setting Background..."
- clitkSetBackground -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/inside_$phase_nb.mhd --mask $mask_dir_tmp/mm_$phase_nb.mhd --outsideValue -1200
- clitkSetBackground -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/outside_$phase_nb.mhd --mask $mask_dir_tmp/mm_$phase_nb.mhd --outsideValue -1200 --fg
-
- # the registration masks for inside (and outside) region correspond
- # to the motion mask (and its complement) plus extra grey value bands,
- # obtained with morphological dilations.
- #
- echo "$phase_file -> Creating registration masks..."
- # inside
- clitkMorphoMath -i $mask_dir_tmp/mm_$phase_nb.mhd -o $mask_dir_tmp/mask_inside_$phase_nb.mhd --type 1 --radius 8
- create_banded_mask $mask_dir_tmp/inside_$phase_nb.mhd $mask_dir_tmp/mm_$phase_nb.mhd $mask_dir_tmp/banded_inside_$phase_nb.mhd $mask_dir_tmp/banded_mask_inside_$phase_nb.mhd 4
- # outside
- clitkExtractPatient -i $mask_dir_tmp/outside_$phase_nb.mhd -o $mask_dir_tmp/mm_outside_$phase_nb.mhd --noAutoCrop
- clitkMorphoMath -i $mask_dir_tmp/mm_outside_$phase_nb.mhd -o $mask_dir_tmp/mask_outside_$phase_nb.mhd --type 1 --radius 8
- create_banded_mask $mask_dir_tmp/outside_$phase_nb.mhd $mask_dir_tmp/mm_outside_$phase_nb.mhd $mask_dir_tmp/banded_outside_$phase_nb.mhd $mask_dir_tmp/banded_mask_outside_$phase_nb.mhd 4
-}
+ extract_patient
-create_registration_lung_masks()
-{
- # extract inside and outside lung regions from the patient image,
- # using the motion mask computed previously
- echo "$phase_file -> Setting Background..."
- clitkSetBackground -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/inside_$phase_nb.mhd --mask $mask_dir_tmp/lungs_$phase_nb.mhd --outsideValue -1200
- clitkSetBackground -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/outside_$phase_nb.mhd --mask $mask_dir_tmp/lungs_$phase_nb.mhd --outsideValue -1200 --fg
+ if [ "$mask_type" != "patient" ]; then
+ extract_lungs
+ fi
- # the registration masks for inside (and outside) region correspond
- # to the motion mask (and its complement) plus extra grey value bands,
- # obtained with morphological dilations.
- #
- echo "$phase_file -> Creating registration masks..."
- # inside
- clitkMorphoMath -i $mask_dir_tmp/lungs_$phase_nb.mhd -o $mask_dir_tmp/mask_inside_$phase_nb.mhd --type 1 --radius 8
- create_banded_mask $mask_dir_tmp/inside_$phase_nb.mhd $mask_dir_tmp/lungs_$phase_nb.mhd $mask_dir_tmp/banded_inside_$phase_nb.mhd $mask_dir_tmp/banded_mask_inside_$phase_nb.mhd 4
- # outside
- clitkBinarizeImage -i $mask_dir_tmp/outside_$phase_nb.mhd -o $mask_dir_tmp/lungs_outside_$phase_nb.mhd -l -999 -u 4000 --mode both
- clitkMorphoMath -i $mask_dir_tmp/lungs_outside_$phase_nb.mhd -o $mask_dir_tmp/mask_outside_$phase_nb.mhd --type 1 --radius 8
- create_banded_mask $mask_dir_tmp/outside_$phase_nb.mhd $mask_dir_tmp/lungs_outside_$phase_nb.mhd $mask_dir_tmp/banded_outside_$phase_nb.mhd $mask_dir_tmp/banded_mask_outside_$phase_nb.mhd 4
-}
+ if [ "$mask_type" == "mm" ]; then
+ extract_bones
+ fi
-mm_preprocessing()
-{
- extract_patient
- extract_bones
- extract_lungs
# remove_tmp_masks 1
if [ $resample_spacing -ne 0 ] ; then
resample
do_mm=1
fi
fi
-# elif [ "$mask_type" == "lungs" ]; then
-# nb_mm_masks=`ls $mask_dir/lungs_outside*.mhd | wc -l`
-# nb_in_masks=`ls $mask_dir/mask_in*.mhd | wc -l`
-# nb_out_masks=`ls $mask_dir/mask_out*.mhd | wc -l`
-# if [ $nb_mm_masks != $nb_phases -o $nb_in_masks != $nb_phases -o $nb_out_masks != $nb_phases ]; then
-# # if the mask dir is invalid, remove it and recreate all masks, just in case.
-# rm -fr $mask_dir 2> /dev/null
-# do_mm=1
-# fi
-# elif [ "$mask_type" == "mm" ]; then
-# nb_mm_masks=`ls $mask_dir/mm_outside*.mhd | wc -l`
-# nb_in_masks=`ls $mask_dir/mask_in*.mhd | wc -l`
-# nb_out_masks=`ls $mask_dir/mask_out*.mhd | wc -l`
-# if [ $nb_mm_masks != $nb_phases -o $nb_in_masks != $nb_phases -o $nb_out_masks != $nb_phases ]; then
-# # if the mask dir is invalid, remove it and recreate all masks, just in case.
-# rm -fr $mask_dir 2> /dev/null
-# do_mm=1
-# fi
-# fi
fi
if [ $do_mm = 1 ]; then
if [ $# -ne 4 -a $# -ne 2 -a $# -ne 1 ]; then
echo "Usage: $0 CT_4D TYPE [RESAMPLE_SPACING RESAMPLE_ALGORITHM]"
- echo " TYPE: \"motion\" (traditional motion masks); \"lungs\" (lung masks); \"patient\" (patient mask only)"
+ echo " TYPE: \"mm\" (traditional motion masks); \"lungs\" (lung masks); \"patient\" (patient mask only)"
exit -1
fi
nb_phases=${#phase_files[@]}
# get everything except numbers and punctuation
- cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "[^0-9[:punct:]]*" | sort -u > /tmp/patterns.txt
+ cat $mhd4d | grep ".z*raw" | sed 's:.z*raw:.mhd:' | sed 's/.mhd//' | grep -o "[^0-9[:punct:]]*" | sort -u > /tmp/patterns.txt
# find which patterns have the phases connected to it
patterns=`cat /tmp/patterns.txt`
if [ -z "$patterns" ]; then
- phase_nbs=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep "[0-9]\+"` )
+ phase_nbs=( `cat $mhd4d | grep ".z*raw" | sed 's:.z*raw:.mhd:' | sed 's/.mhd//' | grep "[0-9]\+"` )
else
for i in $patterns; do
# check if the pattern appears before the phase number
- nb_phases_found=`cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "$i[0-9[:punct:]]\+" | sort -u | wc -l`
+ nb_phases_found=`cat $mhd4d | grep ".z*raw" | sed 's:.z*raw:.mhd:' | sed 's/.mhd//' | grep -o "$i[0-9[:punct:]]\+" | sort -u | wc -l`
if [ $nb_phases_found == $nb_phases ]; then
# keep only what identifies the phase number
- phase_nbs=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "$i[0-9[:punct:]]\+" | grep -o "[^${i}]\+" | grep -o "[0-9]\+[[:punct:]]*[0-9]*" | grep -o "[0-9]*[[:punct:]]*[0-9]\+"` )
+ phase_nbs=( `cat $mhd4d | grep ".z*raw" | sed 's:.z*raw:.mhd:' | sed 's/.mhd//' | grep -o "$i[0-9[:punct:]]\+" | grep -o "[^${i}]\+" | grep -o "[0-9]\+[[:punct:]]*[0-9]*" | grep -o "[0-9]*[[:punct:]]*[0-9]\+"` )
break
fi
# check if the pattern appears after the phase number
- nb_phases_found=`cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "[0-9[:punct:]]\+$i" | sort -u | wc -l`
+ nb_phases_found=`cat $mhd4d | grep ".z*raw" | sed 's:.z*raw:.mhd:' | sed 's/.mhd//' | grep -o "[0-9[:punct:]]\+$i" | sort -u | wc -l`
if [ $nb_phases_found == $nb_phases ]; then
# keep only what identifies the phase number
- phase_nbs=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "[0-9[:punct:]]\+$i" | grep -o "[^${i}]\+" | grep -o "[0-9]\+[[:punct:]]*[0-9]*" | grep -o "[0-9]*[[:punct:]]*[0-9]\+"` )
+ phase_nbs=( `cat $mhd4d | grep ".z*raw" | sed 's:.z*raw:.mhd:' | sed 's/.mhd//' | grep -o "[0-9[:punct:]]\+$i" | grep -o "[^${i}]\+" | grep -o "[0-9]\+[[:punct:]]*[0-9]*" | grep -o "[0-9]*[[:punct:]]*[0-9]\+"` )
break
fi
echo "4D file is $mhd4d"
# array of phase files
- phase_files=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:'` )
+ phase_files=( `cat $mhd4d | grep ".z*raw" | sed 's:.z*raw:.mhd:'` )
echo "Phase files are ${phase_files[@]}"
extract_4d_phase_numbers $mhd4d
extract_4d_phases $1
# reference phase file
- ref_phase_file=`cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | grep $2`
+ ref_phase_file=`cat $mhd4d | grep ".z*raw" | sed 's:.z*raw:.mhd:' | grep $2`
echo "Reference phase is $ref_phase_file"
# reference phase number
local tot=$tmp.mhd
local dir=`dirname $1`
- local first=`grep raw $1 | sed 's/raw/mhd/g' | head -n 1`
+ local first=`grep z*raw $1 | sed 's/z*raw/mhd/g' | head -n 1`
clitkImageArithm -i $dir/$first -o $tot -t 1 -s 0
- local nbphases=`grep raw $1 | sed 's/raw/mhd/g' | wc -l`
- for i in $(grep raw $1 | sed 's/raw/mhd/g'); do
+ local nbphases=`grep z*raw $1 | sed 's/z*raw/mhd/g' | wc -l`
+ for i in $(grep z*raw $1 | sed 's/z*raw/mhd/g'); do
clitkImageArithm -i $dir/$i -j $tot -o $tot
done
clitkImageArithm -i $tot -o $2 -t 11 -s $nbphases
rm $tmp.*
}
+
+select_contour_gui()
+{
+ local roi_list=$@
+ roi=`zenity --list --title="Available Contours" --column="Please choose a contour:" $roi_list`
+ case $? in
+ 0)
+ if [ -z $roi ]
+ then
+ zenity --warning --text="You must choose one contour."
+ select_contour $roi_list
+ else
+ rtstruct_roi_name=$roi
+ fi;;
+ 1)
+ if zenity --question --text="Do you really wish to quit?"
+ then
+ exit
+ else
+ select_contour $roi_list
+ fi;;
+ -1)
+ zenity --error --text="Unexpected error. Please relaunch the application."
+ exit;;
+ esac
+}
+
+select_contour()
+{
+ local roi_list=$@
+ echo "Available Contours:"
+ for r in $roi_list; do
+ echo $r
+ done
+
+ echo "Please choose a contour number:"
+ read rtstruct_roi_index
+ let i=0
+ for r in $roi_list; do
+ if [ $rtstruct_roi_index = `echo $r | cut -d ':' -f 1` ]; then
+ rtstruct_roi_index=$i
+ break;
+ fi
+ let i=i+1
+ done
+
+}
+
+select_roi()
+{
+ rtstruct_roi_name_list=( `clitkDicomInfo ${rtstruct_file} | grep "3006|0026" | cut -d '[' -f 4 | sed 's/| V 3006|0026[LO] [ROI Name] \|]//'` )
+ rtstruct_roi_number_list=( `clitkDicomInfo ${rtstruct_file} | grep "3006|0022" | cut -d '[' -f 4 | sed 's/| V 3006|0026[LO] [ROI Number] \|]//'` )
+ rtstruct_roi_list=( )
+ for i in $(seq 0 1 $(( ${#rtstruct_roi_name_list[@]} - 1 ))); do
+ rtstruct_roi_list[$i]=${rtstruct_roi_number_list[$i]}:${rtstruct_roi_name_list[$i]}
+ done
+
+ if [ $gui_mode = 1 ]; then
+ select_contour_gui ${rtstruct_roi_list[@]}
+ rtstruct_roi=`echo ${rtstruct_roi_name} | cut -d ':' -f 1`
+ rtstruct_roi_name=`echo ${rtstruct_roi_name} | cut -d ':' -f 2`
+ else
+ select_contour ${rtstruct_roi_list[@]}
+ rtstruct_roi=${rtstruct_roi_number_list[$(( $rtstruct_roi_index ))]}
+ rtstruct_roi_name=${rtstruct_roi_name_list[$(( $rtstruct_roi_index ))]}
+ fi
+}
\ No newline at end of file
section "Ellipsoide initialization"
option "ellips" - "Input ellipsoide image (=1, at half resolution)" string no
-option "offset" - "Offset for ellips center from body center of gravity (default= 0,-50,0 mm)" double no multiple
-option "axes" - "Half axes of the ellips (default= 100,30,150)" double no multiple
option "writeEllips" - "Write the initial ellipsoide image" string no
option "writeDistMap" - "Write the distance map" string no
+#defgroup "EllipseParams" groupdesc="an option of this group is required" required
+option "ellipseAutoDetect" - "Auto-detect offset and axes of initial ellipse" flag off
+option "offset" - "Offset for ellips center from body center of gravity (default= 0,-50,0 mm)" double no multiple
+option "axes" - "Half axes of the ellips (default= 100,30,150)" double no multiple
section "Ellipsoide growing"
template <unsigned int Dimension, class PixelType>
typename itk::Image<InternalPixelType, Dimension>::Pointer Resample(typename itk::Image<InternalPixelType, Dimension>::Pointer input );
template <unsigned int Dimension, class PixelType>
- typename itk::Image<InternalPixelType, Dimension>::Pointer InitializeEllips( typename itk::Vector<double,Dimension> center, typename itk::Image<InternalPixelType, Dimension>::Pointer bones_low);
+ typename itk::Image<InternalPixelType, Dimension>::Pointer InitializeEllips( typename itk::Vector<double,Dimension> center, typename itk::Image<InternalPixelType, Dimension>::Pointer bones_low, typename itk::Image<InternalPixelType,Dimension>::Pointer lungs_low);
template <unsigned int Dimension> void UpdateWithDim(std::string PixelType);
*
===================================================*/
+#include "itkLabelImageToShapeLabelMapFilter.h"
+#include "itkShapeLabelObject.h"
namespace clitk
{
//-------------------------------------------------------------------
template <unsigned int Dimension, class PixelType>
typename itk::Image<MotionMaskGenericFilter::InternalPixelType, Dimension>::Pointer
-MotionMaskGenericFilter::InitializeEllips( typename itk::Vector<double,Dimension> center, typename itk::Image<InternalPixelType,Dimension>::Pointer bones_low )
+MotionMaskGenericFilter::InitializeEllips( typename itk::Vector<double,Dimension> center, typename itk::Image<InternalPixelType,Dimension>::Pointer bones_low, typename itk::Image<InternalPixelType,Dimension>::Pointer lungs_low )
{
// ImageTypes
std::cout<<"=========================================="<<std::endl;
}
- //---------------------------------
- // Offset from center
- //---------------------------------
- typename itk::Vector<double,Dimension> offset;
- if(m_ArgsInfo.offset_given== Dimension) {
- for(unsigned int i=0; i<Dimension; i++)
- offset[i]=m_ArgsInfo.offset_arg[i];
- } else {
- offset.Fill(0.);
- offset[1]=-50;
+ itk::Vector<double,Dimension> centerEllips;
+ typename itk::Vector<double, Dimension> axes;
+ if (m_ArgsInfo.ellipseAutoDetect_flag) {
+ if(m_Verbose) {
+ std::cout<<"Auto-detecting intial ellipse..."<<std::endl;
+ }
+
+ typename InternalImageType::RegionType region, region_before = lungs_low->GetLargestPossibleRegion();
+ typename InternalImageType::SizeType size = region_before.GetSize();
+ size[2] /= 2;
+ region.SetSize(size);
+ lungs_low->SetRegions(region);
+
+ // compute statistics of the (mirroed) lung region in order to guess the params of the ellipse
+ typedef itk::LabelImageToShapeLabelMapFilter<InternalImageType> LabelImageToShapeLabelMapFilter;
+ typename LabelImageToShapeLabelMapFilter::Pointer label_filter = LabelImageToShapeLabelMapFilter::New();
+ label_filter->SetInput(lungs_low);
+ label_filter->Update();
+
+ typename InternalImageType::SpacingType spacing = lungs_low->GetSpacing();
+ typedef typename LabelImageToShapeLabelMapFilter::OutputImageType::LabelObjectType LabelType;
+ const LabelType* label = dynamic_cast<LabelType*>(label_filter->GetOutput()->GetNthLabelObject(0));
+
+ // lungs' barycenter
+ typename LabelType::CentroidType lung_centroid = label->GetCentroid();
+
+ // try to guess ideal ellipse axes from the lungs' bounding box and centroid
+ // with some hard-coded "magic" constants...
+#if ITK_VERSION_MAJOR >= 4
+ typename LabelType::RegionType lung_bbox = label->GetBoundingBox();
+#else
+ typename LabelType::RegionType lung_bbox = label->GetRegion();
+#endif
+ axes[0] = 0.95*lung_bbox.GetSize()[0]*spacing[0]/2;
+ axes[1] = 0.3*lung_bbox.GetSize()[1]*spacing[1]/2;
+ axes[2] = 1.25*fabs(lung_centroid[2] - center[2]);
+
+ // ellipse's center in XY is the center of the lungs' bounding box
+ typename InternalImageType::PointType origin = lungs_low->GetOrigin();
+ centerEllips[0] = origin[0] + (lung_bbox.GetIndex()[0] + lung_bbox.GetSize()[0]/2)*spacing[0];
+ centerEllips[1] = origin[1] + (lung_bbox.GetIndex()[1] + lung_bbox.GetSize()[1]/2)*spacing[1];
+ centerEllips[2] = center[2];
+
+ lungs_low->SetRegions(region_before);
+
+ if(m_Verbose) {
+ std::cout << "Lungs'centroid at " << lung_centroid << std::endl;
+ std::cout << "Ellipse center at " << centerEllips << std::endl;
+ std::cout << "Ellipse axes as " << axes << std::endl;
+ std::cout << "Lung's bounding box (index,size) " << lung_bbox.GetIndex() << lung_bbox.GetSize() << std::endl;
+ }
}
- itk::Vector<double,Dimension> centerEllips=center+offset;
- if (m_Verbose) {
- std::cout<<"Placing the center of the initial ellipsoide at (mm) "<<std::endl;
- std::cout<<centerEllips[0];
- for (unsigned int i=1; i<Dimension; i++)
- std::cout<<" "<<centerEllips[i];
- std::cout<<std::endl;
+ else {
+ //---------------------------------
+ // Offset from center
+ //---------------------------------
+ typename itk::Vector<double,Dimension> offset;
+ if(m_ArgsInfo.offset_given== Dimension) {
+ for(unsigned int i=0; i<Dimension; i++)
+ offset[i]=m_ArgsInfo.offset_arg[i];
+ } else {
+ offset.Fill(0.);
+ offset[1]=-50;
+ }
+ centerEllips=center+offset;
+ if (m_Verbose) {
+ std::cout<<"Placing the center of the initial ellipsoide at (mm) "<<std::endl;
+ std::cout<<centerEllips[0];
+ for (unsigned int i=1; i<Dimension; i++)
+ std::cout<<" "<<centerEllips[i];
+ std::cout<<std::endl;
+ }
+
+ // Axes
+ if (m_ArgsInfo.axes_given==Dimension)
+ for(unsigned int i=0; i<Dimension; i++)
+ axes[i]=m_ArgsInfo.axes_arg[i];
+ else {
+ axes[0]=100;
+ axes[1]=30;
+ axes[2]=150;
+ }
}
//---------------------------------
ellips->Allocate();
ellips->FillBuffer(0);
- // Axes
- typename itk::Vector<double, Dimension> axes;
- if (m_ArgsInfo.axes_given==Dimension)
- for(unsigned int i=0; i<Dimension; i++)
- axes[i]=m_ArgsInfo.axes_arg[i];
- else {
- axes[0]=100;
- axes[1]=30;
- axes[2]=150;
- }
-
// Draw an ellips
IteratorType itEllips(ellips, ellips->GetLargestPossibleRegion());
itEllips.GoToBegin();
//----------------------------------------------------------------------------------------------------
// Ellipsoide initialization
//----------------------------------------------------------------------------------------------------
- typename InternalImageType::Pointer m_Ellips= InitializeEllips<Dimension, PixelType>(center,bones_low);
+ typename InternalImageType::Pointer m_Ellips= InitializeEllips<Dimension, PixelType>(center,bones_low,lungs_low);
//----------------------------------------------------------------------------------------------------
// Grow ellips
distanceMapImageFilter->SetInsideIsPositive(false);
if (m_Verbose) std::cout<<"Calculating distance map..."<<std::endl;
distanceMapImageFilter->Update();
+ if (m_ArgsInfo.writeDistMap_given) {
+ writeImage<LevelSetImageType>(distanceMapImageFilter->GetOutput(), m_ArgsInfo.writeDistMap_arg, m_Verbose);
+
+ }
//---------------------------------
// Grow while monitoring lung volume coverage
option "angle" - "Specify the projection angle" float no default="0.0"
option "matrix" - "Rigid tranform prior to projection (4x4)" string no
option "pad" - "Padding value" float no default="0.0"
+option "panel_shift" - "Precise position of the panel in mm" double multiple no
section "Output Image"
iso[i]=m_ArgsInfo.iso_arg[i];
filter->SetIsoCenter(iso);
}
+ if (m_ArgsInfo.panel_shift_given)
+ filter->SetPanelShift(m_ArgsInfo.panel_shift_arg[0], m_ArgsInfo.panel_shift_arg[1]);
filter->SetSourceToScreen(m_ArgsInfo.screen_arg);
filter->SetSourceToAxis(m_ArgsInfo.axis_arg);
filter->SetProjectionAngle(m_ArgsInfo.angle_arg);
clitk::ImageToImageGenericFilter<Self>("ImageConvert")
{
mOutputPixelTypeName = "NotSpecified";
- mWarningOccur = false;
- mWarning = "";
mDisplayWarning = true;
+ mWarning = "";
+ mWarningOccur = false;
+
InitializeImageType<2>();
InitializeImageType<3>();
InitializeImageType<4>();
void clitk::ImageConvertGenericFilter::InitializeImageType()
{
ADD_DEFAULT_IMAGE_TYPES(Dim);
+ ADD_VEC_IMAGE_TYPE(Dim, 2, float);
+ ADD_VEC_IMAGE_TYPE(Dim, 3, float);
+ ADD_VEC_IMAGE_TYPE(Dim, 2, double);
+ ADD_VEC_IMAGE_TYPE(Dim, 3, double);
}
//--------------------------------------------------------------------
template<class InputImageType>
void clitk::ImageConvertGenericFilter::UpdateWithInputImageType()
{
-
// Verbose stuff
if (m_IOVerbose) {
if (m_InputFilenames.size() == 1) {
}
}
-
if ((m_PixelTypeName == mOutputPixelTypeName) || (mOutputPixelTypeName == "NotSpecified")) {
- // typename InputImageType::Pointer input = clitk::readImage<InputImageType>(m_InputFilenames);
typename InputImageType::Pointer input = this->template GetInput<InputImageType>(0);
- //clitk::writeImage<InputImageType>(input, mOutputFilename, m_IOVerbose);
this->SetNextOutput<InputImageType>(input);
} else {
-#define TRY_TYPE(TYPE) \
- if (IsSameType<TYPE>(mOutputPixelTypeName)) { UpdateWithOutputType<InputImageType, TYPE>(); return; }
- TRY_TYPE(char);
- // TRY_TYPE(signed char);
- TRY_TYPE(uchar);
- TRY_TYPE(short);
- TRY_TYPE(ushort);
- TRY_TYPE(int); // no uint ...
- TRY_TYPE(float);
- TRY_TYPE(double);
-#undef TRY_TYPE
-
- std::string list = CreateListOfTypes<char, uchar, short, ushort, int, float, double>();
- std::cerr << "Error, I don't know the output type '" << mOutputPixelTypeName
- << "'. " << std::endl << "Known types are " << list << "." << std::endl;
- exit(0);
+ // "trick" to call independent versions of update according to the
+ // pixel type (vector or scalar), using partial specializations
+ if (!UpdateWithSelectiveOutputType<InputImageType, ImageConvertTraits<typename InputImageType::PixelType>::IS_VECTOR>::Run(*this, mOutputPixelTypeName))
+ exit(-1);
}
}
//====================================================================
//====================================================================
-template<class InputImageType, class OutputPixelType>
-void clitk::ImageConvertGenericFilter::UpdateWithOutputType()
-{
- // Read
- typename InputImageType::Pointer input =this->template GetInput<InputImageType>(0);
-
- // Typedef
- typedef typename InputImageType::PixelType PixelType;
- // Warning
+template<class PixelType, class OutputPixelType>
+void clitk::ImageConvertGenericFilter::CheckTypes(
+ std::string inType, std::string outType
+)
+{
std::ostringstream osstream;
if (std::numeric_limits<PixelType>::is_signed) {
if (!std::numeric_limits<OutputPixelType>::is_signed) {
- osstream << "Warning, input type is signed (" << m_PixelTypeName << ") while output type is not ("
- << mOutputPixelTypeName << "), use at your own responsability." << std::endl;
- mWarningOccur = true;
+ osstream << "Warning, input type is signed (";
}
}
if (!std::numeric_limits<PixelType>::is_integer) {
if (std::numeric_limits<OutputPixelType>::is_integer) {
- osstream << "Warning, input type is not integer (" << m_PixelTypeName << ") while output type is ("
- << mOutputPixelTypeName << "), use at your own responsability." << std::endl;
- mWarningOccur = true;
+ osstream << "Warning, input type is not integer (";
}
}
// DD(std::numeric_limits<PixelType>::digits10);
// DD(std::numeric_limits<OutputPixelType>::digits10);
if (!std::numeric_limits<PixelType>::is_integer) {
if (std::numeric_limits<OutputPixelType>::is_integer) {
- osstream << "Warning, input type is not integer (" << m_PixelTypeName << ") while output type is ("
- << mOutputPixelTypeName << "), use at your own responsability." << std::endl;
- mWarningOccur = true;
+ osstream << "Warning, input type is not integer (";
}
}
if (std::numeric_limits<PixelType>::digits10 > std::numeric_limits<OutputPixelType>::digits10) {
- osstream << "Warning, possible loss of precision : input type is (" << m_PixelTypeName << ") while output type is ("
- << mOutputPixelTypeName << "), use at your own responsability." << std::endl;
- mWarningOccur = true;
+ osstream << "Warning, possible loss of precision : input type is (" ;
}
- mWarning = osstream.str();
- if (mDisplayWarning) {
- std::cerr << mWarning;
+ if (!osstream.str().empty())
+ {
+ mWarningOccur = true;
+ osstream << inType << ") while output type is (" << outType << "), use at your own responsability." << std::endl;
+ mWarning = osstream.str();
+ if (mDisplayWarning) {
+ std::cerr << mWarning;
+ }
}
-
- // Cast
- typedef itk::Image<OutputPixelType,InputImageType::ImageDimension> OutputImageType;
- typedef itk::CastImageFilter<InputImageType, OutputImageType> FilterType;
- typename FilterType::Pointer filter = FilterType::New();
- filter->SetInput(input);
- filter->Update();
-
- // Write
- SetNextOutput<OutputImageType>(filter->GetOutput());
- //clitk::writeImage<OutputImageType>(filter->GetOutput(), mOutputFilename, m_IOVerbose);
}
-//====================================================================
#endif /* end #define CLITKIMAGECONVERTGENERICFILTER_CXX */
// itk include
#include "itkCastImageFilter.h"
+#include "itkVectorCastImageFilter.h"
+
namespace clitk {
+ template <class TPixel>
+ class ImageConvertTraits
+ {
+ public:
+ enum { IS_VECTOR = false };
+ ImageConvertTraits() {
+ TPixel p = "SCALAR";
+ }
+ };
+
+ template < class TPixel, unsigned int Comp >
+ class ImageConvertTraits< itk::Vector<TPixel, Comp> >
+ {
+ public:
+ enum { IS_VECTOR = true };
+ };
+
class ImageConvertGenericFilter:
public clitk::ImageToImageGenericFilter<ImageConvertGenericFilter> {
itkNewMacro(Self);
// Members functions
+ std::string GetInputPixelTypeName() { return m_PixelTypeName; }
+ std::string GetOutputPixelTypeName() { return mOutputPixelTypeName; }
void SetOutputPixelType(std::string p) { mOutputPixelTypeName = p; }
bool IsWarningOccur() { return mWarningOccur; }
std::string & GetWarning() { return mWarning; }
template<class InputImageType>
void UpdateWithInputImageType();
+ template<class PixelType, class OutputPixelType>
+ void CheckTypes(std::string inType, std::string outType);
+
protected:
+
template<unsigned int Dim> void InitializeImageType();
std::string mOutputPixelTypeName;
std::string mWarning;
bool mWarningOccur;
bool mDisplayWarning;
- template<class InputImageType, class OutputPixelType> void UpdateWithOutputType();
-
+ private:
+ template <class InputImageType, bool isVector>
+ class UpdateWithSelectiveOutputType
+ {
+ public:
+ static bool Run(ImageConvertGenericFilter& filter, std::string outputPixelType)
+ {
+ if (IsSameType<char>(outputPixelType))
+ UpdateWithOutputType<char>(filter);
+ else if (IsSameType<uchar>(outputPixelType))
+ UpdateWithOutputType<uchar>(filter);
+ else if (IsSameType<short>(outputPixelType))
+ UpdateWithOutputType<short>(filter);
+ else if (IsSameType<ushort>(outputPixelType))
+ UpdateWithOutputType<ushort>(filter);
+ else if (IsSameType<int>(outputPixelType))
+ UpdateWithOutputType<int>(filter);
+ else if (IsSameType<float>(outputPixelType))
+ UpdateWithOutputType<float>(filter);
+ else if (IsSameType<double>(outputPixelType))
+ UpdateWithOutputType<double>(filter);
+ else
+ {
+ std::string list = CreateListOfTypes<float, double>();
+ std::cerr << "Error, I don't know the vector output type '" << outputPixelType
+ << "'. " << std::endl << "Known types are " << list << "." << std::endl;
+ return false;
+ }
+
+ return true;
+ }
+
+ private:
+
+ template <class OutputPixelType>
+ static void UpdateWithOutputType(ImageConvertGenericFilter& filter)
+ {
+ // Read
+ typename InputImageType::Pointer input =filter.template GetInput<InputImageType>(0);
+
+ // Typedef
+ typedef typename InputImageType::PixelType PixelType;
+
+ // Warning
+ filter.CheckTypes<PixelType, OutputPixelType>(filter.GetInputPixelTypeName(), filter.GetOutputPixelTypeName());
+
+ // Cast
+ typedef itk::Image<OutputPixelType,InputImageType::ImageDimension> OutputImageType;
+ typedef itk::CastImageFilter<InputImageType, OutputImageType> FilterType;
+ typename FilterType::Pointer cast_filter = FilterType::New();
+ cast_filter->SetInput(input);
+ cast_filter->Update();
+
+ // Write
+ filter.SetNextOutput<OutputImageType>(cast_filter->GetOutput());
+ }
+ };
+
+ template <class InputImageType>
+ class UpdateWithSelectiveOutputType<InputImageType, true>
+ {
+ public:
+ static bool Run(ImageConvertGenericFilter& filter, std::string outputPixelType)
+ {
+ /*
+ // RP: future conversions?
+ if (IsSameType<char>(outputPixelType))
+ UpdateWithOutputVectorType<char>();
+ else if (IsSameType<uchar>(outputPixelType))
+ UpdateWithOutputVectorType<uchar>();
+ else if (IsSameType<short>(outputPixelType))
+ UpdateWithOutputVectorType<short>();
+ else if (IsSameType<ushort>(outputPixelType))
+ UpdateWithOutputVectorType<ushort>();
+ else if (IsSameType<int>(outputPixelType))
+ UpdateWithOutputVectorType<int>();
+ else
+ */
+ if (IsSameType<float>(outputPixelType))
+ UpdateWithOutputVectorType<float>(filter);
+ else if (IsSameType<double>(outputPixelType))
+ UpdateWithOutputVectorType<double>(filter);
+ else
+ {
+ std::string list = CreateListOfTypes<float, double>();
+ std::cerr << "Error, I don't know the vector output type '" << outputPixelType
+ << "'. " << std::endl << "Known types are " << list << "." << std::endl;
+ return false;
+ }
+
+ return true;
+ }
+
+ private:
+
+ template <class OutputPixelType>
+ static void UpdateWithOutputVectorType(ImageConvertGenericFilter& filter)
+ {
+ // Read
+ typename InputImageType::Pointer input =filter.template GetInput<InputImageType>(0);
+
+ // Typedef
+ typedef typename InputImageType::PixelType::ValueType PixelType;
+
+ // Warning
+ filter.CheckTypes<PixelType, OutputPixelType>(filter.GetInputPixelTypeName(), filter.GetOutputPixelTypeName());
+
+ // Cast
+ typedef itk::Image<itk::Vector<OutputPixelType, InputImageType::PixelType::Dimension>, InputImageType::ImageDimension> OutputImageType;
+ typedef itk::VectorCastImageFilter<InputImageType, OutputImageType> FilterType;
+ typename FilterType::Pointer cast_filter = FilterType::New();
+ cast_filter->SetInput(input);
+ cast_filter->Update();
+
+ // Write
+ filter.SetNextOutput<OutputImageType>(cast_filter->GetOutput());
+ }
+ };
}; // end class ImageConvertGenericFilter
- //#include "clitkImageConvertGenericFilter.txx"
+//#include "clitkImageConvertGenericFilter.txx"
} // end namespace
//----------------------------------------------------------------------------
// Returns the min an the max value in a 41x41 region around the mouse pointer
-void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max, vtkImageData *image)
+void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max, vtkImageData *image, vtkTransform *transform)
{
//Get mouse pointer position in view coordinates
- double fLocalExtents[6];
+ double corner1[3];
+ double corner2[3];
for(int i=0; i<3; i++) {
- fLocalExtents[i*2 ] = mCurrent[i];
- fLocalExtents[i*2+1] = mCurrent[i];
+ corner1[i] = mCurrent[i];
+ corner2[i] = mCurrent[i];
}
- this->Renderer->WorldToView(fLocalExtents[0], fLocalExtents[2], fLocalExtents[4]);
- this->Renderer->WorldToView(fLocalExtents[1], fLocalExtents[3], fLocalExtents[5]);
- for(int i=0; i<3; i++) {
- if (i!=SliceOrientation) { //SR: assumes that SliceOrientation is valid in ViewCoordinates (???)
- fLocalExtents[i*2 ] -= 0.2;
- fLocalExtents[i*2+1] += 0.2;
- }
- }
- this->Renderer->ViewToWorld(fLocalExtents[0], fLocalExtents[2], fLocalExtents[4]);
- this->Renderer->ViewToWorld(fLocalExtents[1], fLocalExtents[3], fLocalExtents[5]);
+ this->Renderer->WorldToView(corner1[0], corner1[1], corner1[2]);
+ this->Renderer->WorldToView(corner2[0], corner2[1], corner2[2]);
+
+ // In view coordinates, x is the slicer width and y is the slicer height are the in-plane axis
+ int w, h;
+ this->Renderer->GetTiledSize(&w, &h);
+ corner1[0] -= 0.2*h/(double)w;
+ corner2[0] += 0.2*h/(double)w;
+ corner1[1] -= 0.2;
+ corner2[1] += 0.2;
+ this->Renderer->ViewToWorld(corner1[0], corner1[1], corner1[2]);
+ this->Renderer->ViewToWorld(corner2[0], corner2[1], corner2[2]);
//Convert to image pixel coordinates (rounded)
+ transform->TransformPoint(corner1, corner1);
+ transform->TransformPoint(corner2, corner2);
int iLocalExtents[6];
for(int i=0; i<3; i++) {
- fLocalExtents[i*2 ] = (fLocalExtents[i*2 ] - image->GetOrigin()[i])/image->GetSpacing()[i];
- fLocalExtents[i*2+1] = (fLocalExtents[i*2+1] - image->GetOrigin()[i])/image->GetSpacing()[i];
+ corner1[i] = (corner1[i] - image->GetOrigin()[i])/image->GetSpacing()[i];
+ corner2[i] = (corner2[i] - image->GetOrigin()[i])/image->GetSpacing()[i];
- iLocalExtents[i*2 ] = lrint(fLocalExtents[i*2 ]);
- iLocalExtents[i*2+1] = lrint(fLocalExtents[i*2+1]);
+ iLocalExtents[i*2 ] = lrint(corner1[i]);
+ iLocalExtents[i*2+1] = lrint(corner2[i]);
if(iLocalExtents[i*2 ]>iLocalExtents[i*2+1])
std::swap(iLocalExtents[i*2], iLocalExtents[i*2+1]);
void SetCornerAnnotationVisibility(bool s);
bool GetCornerAnnotationVisibility();
- void GetExtremasAroundMousePointer(double & min, double & max, vtkImageData *image);
+ void GetExtremasAroundMousePointer(double & min, double & max, vtkImageData *image, vtkTransform *transform);
void UpdateLandmarks();
void ForceUpdateDisplayExtent();
double min, max;
int t = this->mSlicers[slicer]->GetTSlice();
if(bCtrlKey && this->mSlicers[slicer]->GetFusion()) {
- this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, this->mSlicers[slicer]->GetFusion()->GetVTKImages()[t]);
+ this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max,
+ this->mSlicers[slicer]->GetFusion()->GetVTKImages()[t],
+ this->mSlicers[slicer]->GetFusion()->GetTransform());
this->SetFusionWindow(max-min);
this->SetFusionLevel(0.5*(min+max));
this->SetColorMap(mColorMap);
}
else if(bCtrlKey && this->mSlicers[slicer]->GetOverlay()) {
- this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, this->mSlicers[slicer]->GetOverlay()->GetVTKImages()[t]);
+ this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max,
+ this->mSlicers[slicer]->GetOverlay()->GetVTKImages()[t],
+ this->mSlicers[slicer]->GetOverlay()->GetTransform());
if(this->mSlicers[slicer]->GetLinkOverlayWindowLevel()){
this->SetColorWindow(max-min);
this->SetColorLevel(0.5*(min+max));
}
}
else {
- this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, this->mSlicers[slicer]->GetInput());
+ this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max,
+ this->mSlicers[slicer]->GetImage()->GetVTKImages()[t],
+ this->mSlicers[slicer]->GetImage()->GetTransform());
this->SetColorWindow(max-min);
this->SetColorLevel(0.5*(min+max));
this->SetPreset(6);