diff --git a/Plugins/org.mitk.gui.qt.examples/src/internal/colourimageprocessing/mitkColourImageProcessor.cpp b/Plugins/org.mitk.gui.qt.examples/src/internal/colourimageprocessing/mitkColourImageProcessor.cpp index aa7a355e71..d35fc7d4cd 100644 --- a/Plugins/org.mitk.gui.qt.examples/src/internal/colourimageprocessing/mitkColourImageProcessor.cpp +++ b/Plugins/org.mitk.gui.qt.examples/src/internal/colourimageprocessing/mitkColourImageProcessor.cpp @@ -1,987 +1,988 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkColourImageProcessor.h" #include #include #include +#include namespace mitk { mitkColourImageProcessor::mitkColourImageProcessor() { } mitkColourImageProcessor::~mitkColourImageProcessor() { } template class ScalarToRGBAConverter { const T *dataPtr; unsigned char *tmpPtr; int sizeX; int sizeY; int sizeZ; int sizeXY; int sizeXm1; int sizeYm1; int sizeZm1; mitk::TransferFunction::Pointer tf; public: ScalarToRGBAConverter( const T *_dataPtr,unsigned char *_tmpPtr,int _sizeX,int _sizeY,int _sizeZ,mitk::TransferFunction::Pointer _tf ) { dataPtr=_dataPtr; tmpPtr=_tmpPtr; sizeX=_sizeX; sizeY=_sizeY; sizeZ=_sizeZ; sizeXY=sizeX*sizeY; sizeXm1=sizeX-1; sizeYm1=sizeY-1; sizeZm1=sizeZ-1; tf=_tf; } inline float sample(int x,int y,int z) { return float(dataPtr[ x + y * sizeX + z * sizeXY ]); } inline int clamp(int x) { if(x<0) x=0; else if(x>255) x=255; return x; } inline void write(int x,int y,int z,float grayValue,float gx,float gy,float gz) { /* gx /= aspect[0]; gy /= aspect[1]; gz /= aspect[2]; */ // Compute the gradient magnitude float t = sqrtf( gx*gx + gy*gy + gz*gz ); int doff = x + y * sizeX + z * sizeXY; vtkPiecewiseFunction* opacityTransferFunction = tf->GetScalarOpacityFunction(); vtkPiecewiseFunction* gradientTransferFunction = tf->GetGradientOpacityFunction(); vtkColorTransferFunction* colorTransferFunction = tf->GetColorTransferFunction(); double rgb[3]; colorTransferFunction->GetColor( double(grayValue), rgb); double opacity= opacityTransferFunction->GetValue( double(grayValue) ); opacity *= gradientTransferFunction->GetValue( double(0.5f*t) ); tmpPtr[doff*4+0] = int( rgb[0]*255 + 0.5 ); tmpPtr[doff*4+1] = int( rgb[1]*255 + 0.5 ); tmpPtr[doff*4+2] = int( rgb[2]*255 + 0.5 ); tmpPtr[doff*4+3] = int( opacity*255 + 0.5 ); } inline void compute(int x,int y,int z) { float grayValue = sample(x,y,z); float gx,gy,gz; gx = sample(x+1,y,z) - sample(x-1,y,z); gy = sample(x,y+1,z) - sample(x,y-1,z); gz = sample(x,y,z+1) - sample(x,y,z-1); write( x, y, z, grayValue, gx, gy, gz ); } inline void computeClamp(int x,int y,int z) { float grayValue = sample(x,y,z); float gx,gy,gz; if(x==0) gx = 2.0f * ( sample(x+1,y,z) - grayValue ); else if(x==sizeXm1) gx = 2.0f * ( grayValue - sample(x-1,y,z) ); else gx = sample(x+1,y,z) - sample(x-1,y,z); if(y==0) gy = 2.0f * ( sample(x,y+1,z) - grayValue ); else if(y==sizeYm1) gy = 2.0f * ( grayValue - sample(x,y-1,z) ); else gy = sample(x,y+1,z) - sample(x,y-1,z); if(z==0) gz = 2.0f * ( sample(x,y,z+1) - grayValue ); else if(z==sizeZm1) gz = 2.0f * ( grayValue - sample(x,y,z-1) ); else gz = sample(x,y,z+1) - sample(x,y,z-1); write( x, y, z, grayValue, gx, gy, gz ); } inline void compute1D(int y,int z) { int x; x=0; computeClamp(x,y,z); x++; while(x mitk::Image::Pointer mitkColourImageProcessor::ScalarToRGBA( itk::Image* input , mitk::TransferFunction::Pointer tf) { const TType *inputData=input->GetBufferPointer(); typename itk::Image::SizeType ioSize = input->GetLargestPossibleRegion().GetSize(); MITK_INFO << "size input image: " << ioSize[0] << ", " << ioSize[1] << ", " << ioSize[2]; MITK_INFO << "size voxel: " << ioSize[0] * ioSize[1] * ioSize[2]; int voxel = ioSize[0] * ioSize[1] * ioSize[2]; unsigned char* RGBABuffer = new unsigned char[4*voxel]; // Convert volume { ScalarToRGBAConverter strc(inputData,RGBABuffer,ioSize[0],ioSize[1],ioSize[2],tf); strc.fillSlices(); } // Create MITK Image out of the raw data { mitk::Image::Pointer image = mitk::Image::New(); unsigned int dimensions[ 3 ]; dimensions[ 0 ] = ioSize[0]; dimensions[ 1 ] = ioSize[1]; dimensions[ 2 ] = ioSize[2]; mitk::PixelType pixelType( MakePixelType() ); image->Initialize( pixelType, 3, dimensions ); image->SetImportChannel( RGBABuffer, 0, Image::ManageMemory ); return image; } } mitk::Image::Pointer mitkColourImageProcessor::convertToRGBAImage( mitk::Image::Pointer mitkInput , mitk::TransferFunction::Pointer tf ) { MITK_INFO << "convertToRGBAImage" ; mitk::Image::Pointer mitkResult= mitk::Image::New(); if (mitkInput->GetPixelType().GetComponentType() == itk::ImageIOBase::CHAR) { //cast to itkImage itk::Image< unsigned char, 3 >::Pointer itkInput; mitk::CastToItkImage(mitkInput,itkInput); mitkResult = ScalarToRGBA(itkInput, tf); } else if (mitkInput->GetPixelType().GetComponentType() == itk::ImageIOBase::SHORT) { //cast to itkImage itk::Image< short, 3 >::Pointer itkInput; mitk::CastToItkImage(mitkInput,itkInput); mitkResult = ScalarToRGBA(itkInput, tf); } else { MITK_ERROR << "unsupported pixel type"; return NULL; } mitkResult->SetSpacing( mitkInput->GetGeometry()->GetSpacing() ); return mitkResult; } template class ScalarBinaryToRGBAConverter { const T *dataPtr; const B *data2Ptr; unsigned char *tmpPtr; int sizeX; int sizeY; int sizeZ; int sizeXY; int sizeXm1; int sizeYm1; int sizeZm1; mitk::TransferFunction::Pointer tf; public: ScalarBinaryToRGBAConverter( const T *_dataPtr,const B *_data2Ptr,unsigned char *_tmpPtr,int _sizeX,int _sizeY,int _sizeZ,mitk::TransferFunction::Pointer _tf ) { dataPtr=_dataPtr; data2Ptr=_data2Ptr; tmpPtr=_tmpPtr; sizeX=_sizeX; sizeY=_sizeY; sizeZ=_sizeZ; sizeXY=sizeX*sizeY; sizeXm1=sizeX-1; sizeYm1=sizeY-1; sizeZm1=sizeZ-1; tf=_tf; } inline float sample(int x,int y,int z) { return float(dataPtr[ x + y * sizeX + z * sizeXY ]); } inline bool sampleBinary(int x,int y,int z) { return data2Ptr[ x + y * sizeX + z * sizeXY ]; } inline int clamp(int x) { if(x<0) x=0; else if(x>255) x=255; return x; } inline void write(int x,int y,int z,float grayValue,float gx,float gy,float gz) { if(sampleBinary(x,y,z)) { /* gx /= aspect[0]; gy /= aspect[1]; gz /= aspect[2]; */ // Compute the gradient magnitude float t = sqrtf( gx*gx + gy*gy + gz*gz ); int doff = x + y * sizeX + z * sizeXY; vtkPiecewiseFunction* opacityTransferFunction = tf->GetScalarOpacityFunction(); vtkPiecewiseFunction* gradientTransferFunction = tf->GetGradientOpacityFunction(); vtkColorTransferFunction* colorTransferFunction = tf->GetColorTransferFunction(); double rgb[3]; colorTransferFunction->GetColor( double(grayValue), rgb); double opacity= opacityTransferFunction->GetValue( double(grayValue) ); opacity *= gradientTransferFunction->GetValue( double(0.5f*t) ); tmpPtr[doff*4+0] = int( rgb[0]*255 + 0.5 ); tmpPtr[doff*4+1] = int( rgb[1]*255 + 0.5 ); tmpPtr[doff*4+2] = int( rgb[2]*255 + 0.5 ); tmpPtr[doff*4+3] = int( opacity*255 + 0.5 ); } else { int doff = x + y * sizeX + z * sizeXY; tmpPtr[doff*4+0] = 0; tmpPtr[doff*4+1] = 0; tmpPtr[doff*4+2] = 0; tmpPtr[doff*4+3] = 0; } } inline void compute(int x,int y,int z) { float grayValue = sample(x,y,z); float gx,gy,gz; gx = sample(x+1,y,z) - sample(x-1,y,z); gy = sample(x,y+1,z) - sample(x,y-1,z); gz = sample(x,y,z+1) - sample(x,y,z-1); write( x, y, z, grayValue, gx, gy, gz ); } inline void computeClamp(int x,int y,int z) { float grayValue = sample(x,y,z); float gx,gy,gz; if(x==0) gx = 2.0f * ( sample(x+1,y,z) - grayValue ); else if(x==sizeXm1) gx = 2.0f * ( grayValue - sample(x-1,y,z) ); else gx = sample(x+1,y,z) - sample(x-1,y,z); if(y==0) gy = 2.0f * ( sample(x,y+1,z) - grayValue ); else if(y==sizeYm1) gy = 2.0f * ( grayValue - sample(x,y-1,z) ); else gy = sample(x,y+1,z) - sample(x,y-1,z); if(z==0) gz = 2.0f * ( sample(x,y,z+1) - grayValue ); else if(z==sizeZm1) gz = 2.0f * ( grayValue - sample(x,y,z-1) ); else gz = sample(x,y,z+1) - sample(x,y,z-1); write( x, y, z, grayValue, gx, gy, gz ); } inline void compute1D(int y,int z) { int x; x=0; computeClamp(x,y,z); x++; while(x mitk::Image::Pointer mitkColourImageProcessor::ScalarAndBinaryToRGBA(itk::Image* input ,itk::Image* input2 , mitk::TransferFunction::Pointer tf) { const TType *inputData=input->GetBufferPointer(); const BType *input2Data=input2->GetBufferPointer(); typename itk::Image::SizeType ioSize = input->GetLargestPossibleRegion().GetSize(); MITK_INFO << "size input image: " << ioSize[0] << ", " << ioSize[1] << ", " << ioSize[2]; MITK_INFO << "size voxel: " << ioSize[0] * ioSize[1] * ioSize[2]; int voxel= ioSize[0] * ioSize[1] * ioSize[2]; unsigned char* RGBABuffer = new unsigned char[4*voxel]; //for(int i=0;i strc(inputData,input2Data,RGBABuffer,ioSize[0],ioSize[1],ioSize[2],tf); strc.fillSlices(); } // Create MITK Image out of the raw data { mitk::Image::Pointer image = mitk::Image::New(); unsigned int dimensions[ 3 ]; dimensions[ 0 ] = ioSize[0]; dimensions[ 1 ] = ioSize[1]; dimensions[ 2 ] = ioSize[2]; mitk::PixelType pixelType( MakePixelType() ); image->Initialize( pixelType, 3, dimensions ); image->SetImportChannel( RGBABuffer, 0, Image::ManageMemory ); return image; } } mitk::Image::Pointer mitkColourImageProcessor::convertWithBinaryToRGBAImage( mitk::Image::Pointer input1 ,mitk::Image::Pointer input2 , mitk::TransferFunction::Pointer tf ) { MITK_INFO << "convertWithBinaryToRGBAImage" ; itk::Image< short, 3 >::Pointer inputCT; itk::Image< unsigned char, 3 >::Pointer inputBinary; if (input1->GetPixelType().GetComponentType() == itk::ImageIOBase::UCHAR && input2->GetPixelType().GetComponentType() == itk::ImageIOBase::SHORT) { mitk::CastToItkImage(input1,inputBinary); mitk::CastToItkImage(input2,inputCT); } else if (input1->GetPixelType().GetComponentType() == itk::ImageIOBase::SHORT && input2->GetPixelType().GetComponentType() == itk::ImageIOBase::UCHAR) { mitk::CastToItkImage(input1,inputCT); mitk::CastToItkImage(input2,inputBinary); } else { MITK_ERROR << "unsupported pixel type"; return 0; } return ScalarAndBinaryToRGBA(inputCT,inputBinary, tf); } ////////////////////////////////////////// template class ScalarBinaryColorToRGBAConverter { const T *dataPtr; const B *data2Ptr; unsigned char *tmpPtr; int sizeX; int sizeY; int sizeZ; int sizeXY; int sizeXm1; int sizeYm1; int sizeZm1; mitk::TransferFunction::Pointer tf; int *color; public: ScalarBinaryColorToRGBAConverter( const T *_dataPtr,const B *_data2Ptr,unsigned char *_tmpPtr,int _sizeX,int _sizeY,int _sizeZ,mitk::TransferFunction::Pointer _tf ,int *_color) { dataPtr=_dataPtr; data2Ptr=_data2Ptr; tmpPtr=_tmpPtr; sizeX=_sizeX; sizeY=_sizeY; sizeZ=_sizeZ; sizeXY=sizeX*sizeY; sizeXm1=sizeX-1; sizeYm1=sizeY-1; sizeZm1=sizeZ-1; tf=_tf; color = _color; } inline float sample(int x,int y,int z) { return float(dataPtr[ x + y * sizeX + z * sizeXY ]); } inline bool sampleBinary(int x,int y,int z) { return data2Ptr[ x + y * sizeX + z * sizeXY ]; } inline int clamp(int x) { if(x<0) x=0; else if(x>255) x=255; return x; } inline void write(int x,int y,int z,float grayValue,float gx,float gy,float gz) { if(sampleBinary(x,y,z)) { /* gx /= aspect[0]; gy /= aspect[1]; gz /= aspect[2]; */ // Compute the gradient magnitude float t = sqrtf( gx*gx + gy*gy + gz*gz ); int doff = x + y * sizeX + z * sizeXY; vtkPiecewiseFunction* opacityTransferFunction = tf->GetScalarOpacityFunction(); vtkPiecewiseFunction* gradientTransferFunction = tf->GetGradientOpacityFunction(); vtkColorTransferFunction* colorTransferFunction = tf->GetColorTransferFunction(); double rgb[3]; colorTransferFunction->GetColor( double(grayValue), rgb); double opacity= opacityTransferFunction->GetValue( double(grayValue) ); opacity *= gradientTransferFunction->GetValue( double(0.5f*t) ); tmpPtr[doff*4+0] = int( rgb[0]*255 + 0.5 ); tmpPtr[doff*4+1] = int( rgb[1]*255 + 0.5 ); tmpPtr[doff*4+2] = int( rgb[2]*255 + 0.5 ); tmpPtr[doff*4+3] = int( opacity*255 + 0.5 ); tmpPtr[doff*4+0] = color[0]; tmpPtr[doff*4+1] = color[1]; tmpPtr[doff*4+2] = color[2]; } else { int doff = x + y * sizeX + z * sizeXY; tmpPtr[doff*4+0] = 0; tmpPtr[doff*4+1] = 0; tmpPtr[doff*4+2] = 0; tmpPtr[doff*4+3] = 0; } } inline void compute(int x,int y,int z) { float grayValue = sample(x,y,z); float gx,gy,gz; gx = sample(x+1,y,z) - sample(x-1,y,z); gy = sample(x,y+1,z) - sample(x,y-1,z); gz = sample(x,y,z+1) - sample(x,y,z-1); write( x, y, z, grayValue, gx, gy, gz ); } inline void computeClamp(int x,int y,int z) { float grayValue = sample(x,y,z); float gx,gy,gz; if(x==0) gx = 2.0f * ( sample(x+1,y,z) - grayValue ); else if(x==sizeXm1) gx = 2.0f * ( grayValue - sample(x-1,y,z) ); else gx = sample(x+1,y,z) - sample(x-1,y,z); if(y==0) gy = 2.0f * ( sample(x,y+1,z) - grayValue ); else if(y==sizeYm1) gy = 2.0f * ( grayValue - sample(x,y-1,z) ); else gy = sample(x,y+1,z) - sample(x,y-1,z); if(z==0) gz = 2.0f * ( sample(x,y,z+1) - grayValue ); else if(z==sizeZm1) gz = 2.0f * ( grayValue - sample(x,y,z-1) ); else gz = sample(x,y,z+1) - sample(x,y,z-1); write( x, y, z, grayValue, gx, gy, gz ); } inline void compute1D(int y,int z) { int x; x=0; computeClamp(x,y,z); x++; while(x mitk::Image::Pointer mitkColourImageProcessor::ScalarAndBinaryAndColorToRGBA(itk::Image* input ,itk::Image* input2 , mitk::TransferFunction::Pointer tf, int * color) { const TType *inputData=input->GetBufferPointer(); const BType *input2Data=input2->GetBufferPointer(); typename itk::Image::SizeType ioSize = input->GetLargestPossibleRegion().GetSize(); MITK_INFO << "size input image: " << ioSize[0] << ", " << ioSize[1] << ", " << ioSize[2]; MITK_INFO << "size voxel: " << ioSize[0] * ioSize[1] * ioSize[2]; int voxel= ioSize[0] * ioSize[1] * ioSize[2]; unsigned char* RGBABuffer = new unsigned char[4*voxel]; //for(int i=0;i strc(inputData,input2Data,RGBABuffer,ioSize[0],ioSize[1],ioSize[2],tf,color); strc.fillSlices(); } // Create MITK Image out of the raw data { mitk::Image::Pointer image = mitk::Image::New(); unsigned int dimensions[ 3 ]; dimensions[ 0 ] = ioSize[0]; dimensions[ 1 ] = ioSize[1]; dimensions[ 2 ] = ioSize[2]; mitk::PixelType pixelType( MakePixelType() ); image->Initialize( pixelType, 3, dimensions ); image->SetImportChannel( RGBABuffer, 0, Image::ManageMemory ); return image; } } mitk::Image::Pointer mitkColourImageProcessor::convertWithBinaryAndColorToRGBAImage( mitk::Image::Pointer input1 ,mitk::Image::Pointer input2 , mitk::TransferFunction::Pointer tf , int * color) { MITK_INFO << "convertWithBinaryToRGBAImage" ; itk::Image< short, 3 >::Pointer inputCT; itk::Image< unsigned char, 3 >::Pointer inputBinary; if (input1->GetPixelType().GetComponentType() == itk::ImageIOBase::UCHAR && input2->GetPixelType().GetComponentType() == itk::ImageIOBase::SHORT) { mitk::CastToItkImage(input1,inputBinary); mitk::CastToItkImage(input2,inputCT); } else if (input1->GetPixelType().GetComponentType() == itk::ImageIOBase::SHORT && input2->GetPixelType().GetComponentType() == itk::ImageIOBase::UCHAR) { mitk::CastToItkImage(input1,inputCT); mitk::CastToItkImage(input2,inputBinary); } else { MITK_ERROR << "unsupported pixel type"; return 0; } return ScalarAndBinaryAndColorToRGBA(inputCT,inputBinary, tf,color); } static inline int clamp(int x) { if(x<0) x=0; else if(x>255) x=255; return x; } -mitk::Image::Pointer mitkColourImageProcessor::CombineRGBAImage( unsigned char* input ,unsigned char* input2, int sizeX,int sizeY,int sizeZ ) +mitk::Image::Pointer mitkColourImageProcessor::CombineRGBAImage( const unsigned char* input , const unsigned char* input2, int sizeX,int sizeY,int sizeZ ) { int voxel= sizeX*sizeY*sizeZ; unsigned char* RGBABuffer = new unsigned char[4*voxel]; // Convert volume { for( int r=0;r 1.0f) cor = 1.0f/sum; fac1 *= cor; fac2 *= cor; result[0]= clamp(int(fac1 * rgbaInput1[0] + fac2 * rgbaInput2[0] + 0.5f)); result[1]= clamp(int(fac1 * rgbaInput1[1] + fac2 * rgbaInput2[1] + 0.5f)); result[2]= clamp(int(fac1 * rgbaInput1[2] + fac2 * rgbaInput2[2] + 0.5f)); result[3]= clamp(int(fac1 * rgbaInput1[3] + fac2 * rgbaInput2[3] + 0.5f)); */ if( rgbaInput1[3] ) { result[0]= rgbaInput1[0]; result[1]= rgbaInput1[1]; result[2]= rgbaInput1[2]; result[3]= rgbaInput1[3]; } else { result[0]= rgbaInput2[0]; result[1]= rgbaInput2[1]; result[2]= rgbaInput2[2]; result[3]= rgbaInput2[3]; } RGBABuffer[r*4+0]= result[0]; RGBABuffer[r*4+1]= result[1]; RGBABuffer[r*4+2]= result[2]; RGBABuffer[r*4+3]= result[3]; } } // Create MITK Image out of the raw data { mitk::Image::Pointer image = mitk::Image::New(); unsigned int dimensions[ 3 ]; dimensions[ 0 ] = sizeX; dimensions[ 1 ] = sizeY; dimensions[ 2 ] = sizeZ; mitk::PixelType pixelType( MakePixelType() ); image->Initialize( pixelType, 3, dimensions ); image->SetImportChannel( RGBABuffer, 0, Image::ManageMemory ); return image; } } mitk::Image::Pointer mitkColourImageProcessor::combineRGBAImage( mitk::Image::Pointer input1 , mitk::Image::Pointer input2) { // Order access to a whole Image object try { mitk::ImageReadAccessor img1(input1); - const void* data1 = img1.GetData(); + const unsigned char* data1 = (const unsigned char*) img1.GetData(); mitk::ImageReadAccessor img2(input2); - const void* data2 = img2.GetData(); + const unsigned char* data2 = (const unsigned char*) img2.GetData(); unsigned int *dim = input1->GetDimensions(); return CombineRGBAImage(data1,data2,dim[0],dim[1],dim[2]); } catch(mitk::Exception& e) { MITK_ERROR << "mitkColourImageProcessor::combineRGBAImage - No access to image data possible." << e.what(); return NULL; } } }//end namespace mitk diff --git a/Plugins/org.mitk.gui.qt.examples/src/internal/colourimageprocessing/mitkColourImageProcessor.h b/Plugins/org.mitk.gui.qt.examples/src/internal/colourimageprocessing/mitkColourImageProcessor.h index 7c89f5ab78..b915d71aaa 100644 --- a/Plugins/org.mitk.gui.qt.examples/src/internal/colourimageprocessing/mitkColourImageProcessor.h +++ b/Plugins/org.mitk.gui.qt.examples/src/internal/colourimageprocessing/mitkColourImageProcessor.h @@ -1,66 +1,66 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKCOLOURIMAGEPROCESSOR_H #define MITKCOLOURIMAGEPROCESSOR_H #include #include #include #include #include namespace mitk { class mitkColourImageProcessor { public: typedef itk::RGBAPixel RGBAPixel; typedef itk::Image RGBAImage; mitkColourImageProcessor(); ~mitkColourImageProcessor () ; mitk::Image::Pointer convertToRGBAImage( mitk::Image::Pointer input , mitk::TransferFunction::Pointer tf ); mitk::Image::Pointer convertWithBinaryToRGBAImage( mitk::Image::Pointer input1 , mitk::Image::Pointer input2 , mitk::TransferFunction::Pointer tf ); mitk::Image::Pointer convertWithBinaryAndColorToRGBAImage( mitk::Image::Pointer input1 , mitk::Image::Pointer input2 , mitk::TransferFunction::Pointer tf, int* color ); mitk::Image::Pointer combineRGBAImage( mitk::Image::Pointer input1 , mitk::Image::Pointer input2); private: template mitk::Image::Pointer ScalarToRGBA(itk::Image* input , mitk::TransferFunction::Pointer tf); template mitk::Image::Pointer ScalarAndBinaryToRGBA(itk::Image* input ,itk::Image* input2 , mitk::TransferFunction::Pointer tf); template mitk::Image::Pointer ScalarAndBinaryAndColorToRGBA(itk::Image* input ,itk::Image* input2 , mitk::TransferFunction::Pointer tf, int * color); - mitk::Image::Pointer CombineRGBAImage( unsigned char* input ,unsigned char* input2, int sizeX,int sizeY,int sizeZ ); + mitk::Image::Pointer CombineRGBAImage(const unsigned char *input , const unsigned char *input2, int sizeX, int sizeY, int sizeZ ); }; }//end namespace mitk #endif /* MITKCOLOURIMAGEPROCESSOR_H */ diff --git a/Plugins/org.mitk.gui.qt.examples/src/internal/volumetry/QmitkVolumetryView.cpp b/Plugins/org.mitk.gui.qt.examples/src/internal/volumetry/QmitkVolumetryView.cpp index a9b8823860..5f9d7234e3 100644 --- a/Plugins/org.mitk.gui.qt.examples/src/internal/volumetry/QmitkVolumetryView.cpp +++ b/Plugins/org.mitk.gui.qt.examples/src/internal/volumetry/QmitkVolumetryView.cpp @@ -1,330 +1,329 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkVolumetryView.h" #include "mitkNodePredicateDataType.h" #include "QmitkDataStorageComboBox.h" #include "QmitkStdMultiWidget.h" #include #include "itkImage.h" #include #include "mitkDataNode.h" #include "mitkRenderingManager.h" #include "mitkVolumeCalculator.h" #include #include #include const std::string QmitkVolumetryView::VIEW_ID = "org.mitk.views.volumetry"; QmitkVolumetryView::QmitkVolumetryView() : QmitkFunctionality(), m_Controls(NULL), m_MultiWidget(NULL) { //m_DataStorage = this->GetDefaultDataStorage(); } QmitkVolumetryView::~QmitkVolumetryView() { } void QmitkVolumetryView::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkVolumetryViewControls; m_Controls->setupUi(parent); this->CreateConnections(); // define data type for combobox m_Controls->m_ImageSelector->SetDataStorage( this->GetDefaultDataStorage() ); m_Controls->m_ImageSelector->SetPredicate( mitk::NodePredicateDataType::New("Image") ); } } void QmitkVolumetryView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkVolumetryView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } void QmitkVolumetryView::CreateConnections() { if ( m_Controls ) { connect( m_Controls->m_ImageSelector, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnImageSelected(const mitk::DataNode*)) ); //connect( (QObject*)(m_Controls->m_Button), SIGNAL(clicked()), this, SLOT(DoSomething()) ); connect( (QObject*)(m_Controls->m_ThresholdSlider), SIGNAL(valueChanged(int)), this, SLOT(OnThresholdSliderChanged(int)) ); //connect( (QObject*)(m_Controls->m_ThresholdLineEdit), SIGNAL(valueChanged(int)), this, SLOT(OnThresholdLineEdit(int)) ); //connect( (QObject*)(m_Controls->m_TextEdit), SIGNAL(valueChanged(int)), this, SLOT(OnTextEditChanged(int)) ); connect( (QObject*)(m_Controls->m_CalcButton), SIGNAL(clicked()), this, SLOT(OnCalculateVolume()) ); connect( (QObject*)(m_Controls->m_TimeSeriesButton), SIGNAL(clicked()), this, SLOT(OnTimeSeriesButtonClicked()) ); connect( (QObject*)(m_Controls->m_SaveCsvButton), SIGNAL(clicked()), this, SLOT(OnSaveCsvButtonClicked()) ); } } void QmitkVolumetryView::Activated() { QmitkFunctionality::Activated(); } void QmitkVolumetryView::Deactivated() { QmitkFunctionality::Deactivated(); } void QmitkVolumetryView::OnImageSelected(const mitk::DataNode* item) { // nothing selected (NULL selection) if( item == NULL || item->GetData() == NULL ) return; m_SelectedDataNode = const_cast(item); std::cout << "Selected mitk::Image at address " << m_SelectedDataNode->GetData() << std::endl; if(item == m_OverlayNode.GetPointer()) return; if (m_OverlayNode) { this->GetDefaultDataStorage()->Remove(m_OverlayNode); // remove it from the tree //mitk::DataTreeIteratorClone overlayIt = mitk::DataTreeHelper::FindIteratorToNode(m_DataTreeIteratorClone->GetTree(),m_OverlayNode); //if (overlayIt.IsNotNull()) { overlayIt->Remove(); } m_OverlayNode = NULL; } this->CreateOverlayChild(); //std::string name; //if (node->GetName(name)) //{ // // m_TreeNodeNameLabel->setText( name.c_str() ); //} m_Controls->m_CalcButton->setEnabled(false); m_Controls->m_TimeSeriesButton->setEnabled(false); m_Controls->m_SaveCsvButton->setEnabled(false); m_Controls->m_TextEdit->clear(); if (m_SelectedDataNode.IsNotNull() ) { mitk::Image* image = dynamic_cast(m_SelectedDataNode->GetData()); image->Update(); if (image && image->IsInitialized()) { if (image->GetDimension() == 4) { m_Controls->m_TimeSeriesButton->setEnabled(true); } else { m_Controls->m_CalcButton->setEnabled(true); } int minVal = (int)image->GetScalarValue2ndMin(); int maxVal = (int)image->GetScalarValueMaxNoRecompute(); if (minVal == maxVal) --minVal; m_Controls->m_ThresholdSlider->setMinimum(minVal); m_Controls->m_ThresholdSlider->setMaximum(maxVal); m_Controls->m_ThresholdSlider->setEnabled(true); this->UpdateSlider(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } } - void QmitkVolumetryView::OnCalculateVolume() { if (m_SelectedDataNode.IsNotNull() ) { mitk::Image* image = dynamic_cast(m_SelectedDataNode->GetData()); if (image) { std::cout << "Dimension:" << image->GetDimension() << std::endl; std::cout << "Dimension[3]:" << image->GetDimension(3) << std::endl; mitk::VolumeCalculator::Pointer volCalc = mitk::VolumeCalculator::New(); volCalc->SetImage(image); volCalc->SetThreshold(m_Controls->m_ThresholdSlider->value()); volCalc->ComputeVolume(); std::stringstream vs; vs << volCalc->GetVolume() << " ml"; m_Controls->m_Result->setText(vs.str().c_str() ); } } } void QmitkVolumetryView::OnTimeSeriesButtonClicked() { if (m_SelectedDataNode.IsNotNull() ) { mitk::Image* image = dynamic_cast(m_SelectedDataNode->GetData()); if (image) { mitk::VolumeCalculator::Pointer volCalc = mitk::VolumeCalculator::New(); volCalc->SetImage(image); volCalc->SetThreshold(m_Controls->m_ThresholdSlider->value()); volCalc->ComputeVolume(); std::vector volumes = volCalc->GetVolumes(); std::stringstream vs; int timeStep = 0; for (std::vector::iterator it = volumes.begin(); it != volumes.end(); it++) { vs << timeStep++ << "\t" << *it << std::endl; } m_Controls->m_TextEdit->setText(vs.str().c_str()); m_Controls->m_TextEdit->setTabStopWidth(20); m_Controls->m_SaveCsvButton->setEnabled(true); } } } const mitk::DataNode* QmitkVolumetryView::GetImageNode() { return m_SelectedDataNode; } void QmitkVolumetryView::UpdateSlider() { if (m_SelectedDataNode.IsNotNull() && dynamic_cast(m_SelectedDataNode->GetData())) { int intSliderValue = (int)m_Controls->m_ThresholdSlider->value(); QString stringSliderValue; stringSliderValue.setNum(intSliderValue); m_Controls->m_ThresholdLineEdit->setText(stringSliderValue); } } void QmitkVolumetryView::UpdateSliderLabel() { int sliderValue = atoi(m_Controls->m_ThresholdLineEdit->text().toLatin1()); m_Controls->m_ThresholdSlider->setValue(sliderValue); this->UpdateSlider(); } void QmitkVolumetryView::OnThresholdSliderChanged( int value) { if (m_OverlayNode) { m_OverlayNode->SetLevelWindow(mitk::LevelWindow(value,1)); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->UpdateSlider(); } } void QmitkVolumetryView::CreateOverlayChild() { if (m_SelectedDataNode.IsNotNull()) { m_OverlayNode = mitk::DataNode::New(); mitk::StringProperty::Pointer nameProp = mitk::StringProperty::New("volume threshold overlay image" ); m_OverlayNode->SetProperty( "reslice interpolation", m_SelectedDataNode->GetProperty("reslice interpolation") ); m_OverlayNode->SetProperty( "name", nameProp ); m_OverlayNode->SetData(m_SelectedDataNode->GetData()); m_OverlayNode->SetColor(0.0,1.0,0.0); m_OverlayNode->SetOpacity(.25); int layer = 0; m_SelectedDataNode->GetIntProperty("layer", layer); m_OverlayNode->SetIntProperty("layer", layer+1); m_OverlayNode->SetLevelWindow(mitk::LevelWindow(m_Controls->m_ThresholdSlider->value(),1)); this->GetDefaultDataStorage()->Add(m_OverlayNode); //// hack!!! //mitk::DataTreeIteratorClone iteratorClone = m_DataTreeIteratorClone; //while ( !iteratorClone->IsAtEnd() ) //{ // mitk::DataNode::Pointer node = iteratorClone->Get(); // if ( node == m_SelectedDataNode ) // { // iteratorClone->Add(m_OverlayNode); // break; // } // ++iteratorClone; //} } } mitk::DataNode* QmitkVolumetryView::GetOverlayNode() { return m_OverlayNode; } mitk::Image* QmitkVolumetryView::GetImage() { return dynamic_cast(m_SelectedDataNode->GetData()); } void QmitkVolumetryView::OnSaveCsvButtonClicked() { static QString lastSavePath = QDir::homePath(); QString s = QFileDialog::getSaveFileName( this->m_Parent, "Save as..", lastSavePath, "CSV Files (*.csv)"); /*"Save file dialog" "Choose a filename to save under" );*/ if (! s.isEmpty()) { lastSavePath = s; QFile saveFile(s); if ( saveFile.open(QIODevice::WriteOnly)) { QTextStream stream( &saveFile ); stream << m_Controls->m_TextEdit->toPlainText().replace('\t',';'); saveFile.close(); } else { // QMessageBox::critical(NULL,"Save Error!",QString("Saving of CSV failed! Couldn't open output file \"") + saveFile + QString("\""),QMessageBox:Ok,QMessageBox::NoButton); //QMessageBox::critical(NULL,"Save Error!","Saving of CSV failed! Couldn't open output file \"" + saveFile.name() +"\"",QMessageBox::Ok,QMessageBox::NoButton); } } }