X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FcreaImageIOGimmickView.cpp;h=0a76936736294655e38f4d77fa54c0a5790b89f9;hb=bae8afe7ee037a3368be7060c3a0708582e7d413;hp=3132aa69f583d1608780875df2a3a7324df840f4;hpb=3a22e19184c369b130d4caa992a8e98e50c7a0ee;p=creaImageIO.git diff --git a/src/creaImageIOGimmickView.cpp b/src/creaImageIOGimmickView.cpp index 3132aa6..0a76936 100644 --- a/src/creaImageIOGimmickView.cpp +++ b/src/creaImageIOGimmickView.cpp @@ -1,18 +1,55 @@ +/* +# --------------------------------------------------------------------- +# +# Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image +# pour la Santé) +# Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton +# Previous Authors : Laurent Guigues, Jean-Pierre Roux +# CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil +# +# This software is governed by the CeCILL-B license under French law and +# abiding by the rules of distribution of free software. You can use, +# modify and/ or redistribute the software under the terms of the CeCILL-B +# license as circulated by CEA, CNRS and INRIA at the following URL +# http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html +# or in the file LICENSE.txt. +# +# As a counterpart to the access to the source code and rights to copy, +# modify and redistribute granted by the license, users are provided only +# with a limited warranty and the software's author, the holder of the +# economic rights, and the successive licensors have only limited +# liability. +# +# The fact that you are presently reading this means that you have had +# knowledge of the CeCILL-B license and that you accept its terms. +# ------------------------------------------------------------------------ +*/ + + #include -#include + #include "boost/filesystem.hpp" #if defined(USE_GDCM) #include #include +#include +#include #include #endif -#if defined(USE_GDCM2) +/*#if defined(USE_GDCM2) #include +#include "gdcmSystem.h" +#include "gdcmCryptographicMessageSyntax.h" +#include "gdcmUIDGenerator.h" +#include "gdcmAnonymizer.h" +#include "gdcmGlobal.h" +#endif*/ +#if defined(_WIN32) +#pragma warning(disable: 4996) #endif - namespace fs = boost::filesystem; namespace creaImageIO { @@ -23,20 +60,20 @@ namespace creaImageIO public: ImageExtent(const std::string& x, const std::string& y, const std::string& z, const std::string& t) { - sscanf(x.c_str(),"%d",&mExtent[0]); - sscanf(y.c_str(),"%d",&mExtent[1]); - sscanf(z.c_str(),"%d",&mExtent[2]); - sscanf(t.c_str(),"%d",&mExtent[3]); - if(x==""){mExtent[0]=1;} - if(y==""){mExtent[1]=1;} - if(z==""){mExtent[2]=1;} - if(t==""){mExtent[3]=1;} - - if (mExtent[3]>1) mDim=4; - else if (mExtent[2]>1) mDim=3; - else if (mExtent[1]>1) mDim=2; - else if (mExtent[0]>1) mDim=1; - else mDim=0; + sscanf(x.c_str(),"%d",&mExtent[0]); + sscanf(y.c_str(),"%d",&mExtent[1]); + sscanf(z.c_str(),"%d",&mExtent[2]); + sscanf(t.c_str(),"%d",&mExtent[3]); + if(x==""){mExtent[0]=1;} + if(y==""){mExtent[1]=1;} + if(z==""){mExtent[2]=1;} + if(t==""){mExtent[3]=1;} + + if (mExtent[3]>1) mDim=4; + else if (mExtent[2]>1) mDim=3; + else if (mExtent[1]>1) mDim=2; + else if (mExtent[0]>1) mDim=1; + else mDim=0; } @@ -213,10 +250,11 @@ namespace creaImageIO } else { - boost::shared_ptr ie=boost::shared_ptr(new ImageExtent((*sel).GetAttribute("D0028_0010"), + boost::shared_ptr ie=boost::shared_ptr(new ImageExtent((*sel).GetAttribute("D0028_0010"), (*sel).GetAttribute("D0028_0011"), (*sel).GetAttribute("D0028_0012"), "")); + if(mImageExtent==0) { mImageExtent=ie; @@ -286,14 +324,20 @@ namespace creaImageIO //====================================================================== void GimmickView::modifyValidationSignal(bool ivalid) { + mValidationSignal(ivalid); } + void GimmickView::stopReader() + { + mReader.Stop(); + } + //====================================================================== ///Reads Images (Non Threaded) void GimmickView::ReadImagesNotThreaded(std::vector& s, std::vector im, int dimension) { - mReader.Stop(); + stopReader(); /* remember! #define GIMMICK_NO_IMAGE_SELECTION 0 @@ -340,11 +384,11 @@ void GimmickView::ReadImagesNotThreaded(std::vector& s, std::vect if(ext[5] == 0) { - ext[5] = im.size()-1; + ext[5] = (int)im.size()-1; } else { - ext[5] = ext[5] * im.size()-1; // to deal with multiframes - JPR + ext[5] = ext[5] * (int)im.size()-1; // to deal with multiframes - JPR } out->SetExtent(ext); @@ -353,7 +397,7 @@ void GimmickView::ReadImagesNotThreaded(std::vector& s, std::vect int dim[3]; first->GetDimensions(dim); - out->SetDimensions(dim[0], dim[1], im.size() ); + out->SetDimensions(dim[0], dim[1], (int)im.size() ); out->AllocateScalars(); out->Update(); @@ -371,7 +415,11 @@ void GimmickView::ReadImagesNotThreaded(std::vector& s, std::vect double spc[3]; first->GetSpacing(spc); - spc[2]=OrderTheFileNameVector(im); + + // OrderTheFileNameVector is not here anymore. + // Try orderFilesWithZSpacing from OutputModel FCY + // spc[2]=OrderTheFileNameVector(im); + spc[2] =1; out->SetSpacing(spc); @@ -393,63 +441,289 @@ void GimmickView::ReadImagesNotThreaded(std::vector& s, std::vect } //====================================================================== -#if defined(USE_GDCM) - double GimmickView::OrderTheFileNameVector(std::vector &im) -{ - double spacing=1; - typedef std::vector FileList; - FileList fileVector; - //GDCM_NAME_SPACE::File *f = GDCM_NAME_SPACE::File::New(); - GDCM_NAME_SPACE::SerieHelper *sh = GDCM_NAME_SPACE::SerieHelper::New(); - std::vector lstAux; - std::vector::iterator it; - for (it=im.begin(); it!=im.end(); ++it) + + + ////////////////////////////////////////////////////////// + // Test if the image is a multiple or single frame. + // For the moment only with the creation of vtkImageDta. + // TO DO with image size and dim!!! + ////////////////////////////////////////////////////////// + bool GimmickView::isSingle(const std::string i_file) { - ///\TODO liberer les GDCM_NAME_SPACE::File a la fin! // JPR - GDCM_NAME_SPACE::File *f = GDCM_NAME_SPACE::File::New(); - f->SetFileName(*it); - f->Load(); - if (f->IsReadable()) + bool bres = true; + vtkImageData* first = mReader.GetImage( i_file); + int dim[3]; + first->GetDimensions(dim); + if (dim[2] > 1) { - fileVector.push_back(f); - } else { - lstAux.push_back(*it); + bres = false; } - } // for - + else + { + } + return bres; + } + + ////////////////////////////////////////////////////////// + // get Attributes values for a file + ////////////////////////////////////////////////////////// - if ((fileVector.size()>1) && (sh->IsCoherent( &fileVector ))) + void GimmickView::getAttributes(const std::string i_file, std::map &o_infos, OutputAttr i_attr) { - sh->OrderFileList(&fileVector); - spacing= sh->GetZSpacing(); - im.clear(); - int i; - for (i=0; iGetFileName() ); - } - for (i=0; i0) + { + mGimmick->GetAttributes(i_file,o_infos,i_attr); + } + if(i_attr.outside.size()>0) + { + mReader.getAttributes(i_file,o_infos, i_attr.outside); + } + } + + ////////////////////////////////////////////////////////// + // create an output structure with n entries = n output + ////////////////////////////////////////////////////////// + void GimmickView::readImages1(std::vector& o_output, std::vector im, + OutputAttr i_attr) + { + std::vector::iterator it; + for (it=im.begin(); it!=im.end(); ++it) + { + OutStrGimmick out; + out.img = vtkImageData::New(); + out.img->ShallowCopy(mReader.GetImage(*it)); + if(i_attr.mult) + getAttributes((*it),out.infos,i_attr); + o_output.push_back(out); + } + // If we want only one output information structure, we set it outside the loop + if(!i_attr.mult) + { + getAttributes(im.front(), o_output.front().infos, i_attr); + } + + } + + ////////////////////////////////////////////////////////// + // create an output structure with n entries = 1 output + ////////////////////////////////////////////////////////// + void GimmickView::readImages3(std::vector& o_output, std::vector im, + OutputAttr i_attr, double i_zspc) + { + OutStrGimmick out; + vtkImageData* first = mReader.GetImage( im.front()); + out.img = vtkImageData::New(); + out.img->SetScalarType(first->GetScalarType()); + out.img->SetNumberOfScalarComponents(first->GetNumberOfScalarComponents()); + int ext[6]; + first->GetWholeExtent(ext); // send also 0,0 in Z + if(ext[5] == 0) + { + ext[5] = (int)im.size()-1; + } + else + { + ext[5] = ext[5] * (int)im.size()-1; // to deal with multiframes + } + out.img->SetExtent(ext); + int dim[3]; + double spac[3]; + first->GetDimensions(dim); + first->GetSpacing(spac); + out.img->SetSpacing(spac); + out.img->SetDimensions(dim[0], dim[1], (int)im.size() ); + out.img->AllocateScalars(); + out.img->Update(); + unsigned long imsize = dim[0] * dim[1]; + imsize = imsize * dim[2] ; // deal with multiframes here + // differents formats char , short, etc... + // differents components 1..3 ex. jpg ->RGB 3 + imsize = imsize * first->GetScalarSize() * first->GetNumberOfScalarComponents(); + // Order the file name vector already did with the OutputModel!!! + //!!!!out.img->SetSpacing(i_zspc); + int slice = 0; + std::vector::iterator it; + for (it=im.begin(); it!=im.end(); ++it) + { + vtkImageData* cur = mReader.GetImage( (*it) ); + memcpy(out.img->GetScalarPointer(0,0,slice), cur->GetScalarPointer(0,0,0), imsize); + slice++; + } + getAttributes(im.front(),out.infos, i_attr); + o_output.push_back(out); + } + + + // TO DO NO VERY SURE : NEED TO BE TESTED + ////////////////////////////////////////////////////////// + // create an output structure with n entries (T size) = T output (n size) + ////////////////////////////////////////////////////////// + void GimmickView::readImages2(std::vector& o_output, std::vector im, + OutputAttr i_attr, double i_zspc) + { + vtkImageData* first = mReader.GetImage( im.front()); + int dim[3]; + double spac[3]; + first->GetDimensions(dim); + first->GetSpacing(spac); + // differents formats char , short, etc... + // differents components 1..3 ex. jpg ->RGB 3 + unsigned long imsize = dim[0] * dim[1]; + imsize = imsize * first->GetScalarSize() * first->GetNumberOfScalarComponents(); + + // Order the file name vector already did with the OutputModel!!! + std::vector::iterator it; + std::vector::iterator it_out = o_output.begin(); + + for (it=im.begin(); it!=im.end(); ++it)//, it_out ++) + { + vtkImageData* cur = mReader.GetImage( (*it) ); + for (int slice= 0 ; slice SetScalarType(first->GetScalarType()); + out.img->SetSpacing(spac); + out.img->SetNumberOfScalarComponents(first->GetNumberOfScalarComponents()); + int ext[6]; + first->GetWholeExtent(ext); // send also 0,0 in Z + ext[5] = 0; + out.img->SetExtent(ext); + + out.img->SetDimensions(dim[0], dim[1], 1 ); + out.img->AllocateScalars(); + out.img->Update(); + memcpy(out.img->GetScalarPointer(0,0,0), cur->GetScalarPointer(0,0,slice), imsize); + o_output.push_back(out); } - }else { - std::sort( im.begin(), im.end() ); + // if(i_attr.mult) + // getAttributes((*it),(*it_out).infos,i_attr); + } + if(!i_attr.mult) + { + getAttributes(im.front(), o_output.front().infos,i_attr); + } + } + + ////////////////////////////////////////////////////////// + // create an output structure with n entries (T size) = T + n output + ////////////////////////////////////////////////////////// + void GimmickView::readImages4(std::vector& o_output, std::vector im, + OutputAttr i_attr) + { + std::vector::iterator it; + std::vector::iterator it_out = o_output.begin(); + vtkImageData* first = mReader.GetImage( im.front()); + int dim[3]; + first->GetDimensions(dim); - return spacing; -} + for (int slice= 0 ; slice SetScalarType(first->GetScalarType()); + out.img->SetNumberOfScalarComponents(first->GetNumberOfScalarComponents()); + + int ext[6]; + double spac[6]; + first->GetWholeExtent(ext); // send also 0,0 in Z + ext[5] = 0; + out.img->SetExtent(ext); + first->GetSpacing(spac); + out.img->SetSpacing(spac); + out.img->SetDimensions(dim[0], dim[1], (int)im.size() ); + out.img->AllocateScalars(); + out.img->Update(); + unsigned long imsize = dim[0] * dim[1]; + imsize = imsize * first->GetScalarSize() * first->GetNumberOfScalarComponents(); + int index = 0; + + for (it=im.begin(); it!=im.end(); ++it, index ++) + { + vtkImageData* cur = mReader.GetImage( (*it) ); + memcpy(out.img->GetScalarPointer(0,0,index), cur->GetScalarPointer(0,0,slice), imsize); + o_output.push_back(out); + } + } + if(!i_attr.mult) // No sense to take informations in all images + { + getAttributes(im.front(), o_output.front().infos,i_attr); + } + } -#endif -#if defined(USE_GDCM2) - // TO DO - double GimmickView::OrderTheFileNameVector(std::vector &im) +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Global function to read Images and create wished output (informations, multiple, type and size of output...) +// In function of type (file, vector) and size, the correct readImages function is selected +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void GimmickView::readImages(std::vector& o_output, std::vector im, + OutputAttr i_attr, int i_dim, double i_zspc) { - return 1; + int size = (int)im.size(); + if ( size == 0) + { + return; + } + else if (size == 1) + { + // Simplest case + // Only one image : give it + // But take in count multiframe possibility + if ( isSingle(im.front()) || i_dim != 1) + { + readImages1(o_output,im, i_attr); + } + else + { + readImages2(o_output,im, i_attr,i_zspc); + } + } else { + // multiple or single frame + if ( isSingle(im.front()) ) + { + //we deal with 2D images + if(i_dim == 1) + { + // 2D to 3D + readImages3(o_output,im, i_attr,i_zspc); + } + else + { + readImages1(o_output,im, i_attr); + } + } + else + { + // we deal with multiple frames n x (2D x T) + // Differents outputs are avaialable + if(i_dim == 1) + { + // put all in one output + readImages3(o_output,im, i_attr,i_zspc); + + } + else if( i_dim == 2) + { + // put in a vector of n x T (2D) + readImages2(o_output,im, i_attr,i_zspc); + } + else if( i_dim == 3) + { + // put in a vector of n (2D x T) + // No transformations. + readImages1(o_output,im, i_attr); + } + else + { + // put in a vector of T (2D x n) + readImages4(o_output,im, i_attr); + } + } + } } -#endif -//====================================================================== + void GimmickView::ReadImagesNotThreadedInVector(std::vector& s, std::vector im, int dimension) @@ -467,6 +741,7 @@ void GimmickView::ReadImagesNotThreadedInVector(std::vector& s, s } else if (im.size()>1) // Test inutile ? JPR { + /// \TODO fix unused variable 'first' vtkImageData* first = mReader.GetImage( im.front()); if (dimension == 2) { @@ -591,53 +866,172 @@ void GimmickView::ReadImagesNotThreadedInVector(std::vector& s, s mValidationSignal.connect(callback); } -} // EO namespace creaImageIO -////////////////////////////////////////////////////////////////////// +#if defined(USE_GDCM) +//////////////////////////////////////////////////////////////////////// +void GimmickView::Anonymize(std::vector i_filenames, int type) +{ + bool res = true; + std::vector filesH; + std::vector suid; + std::map msuid; + std::string tempuid = GDCM_NAME_SPACE::Util::CreateUniqueUID(); + int i = 1; + std::vector::iterator it = i_filenames.begin(); + for(; it != i_filenames.end(); it++) + { + + GDCM_NAME_SPACE::File *file; + file = GDCM_NAME_SPACE::File::New( ); + file->SetLoadMode( GDCM_NAME_SPACE::LD_ALL ); + file->SetFileName( (*it).c_str() ); + res = file->Load(); + if ( !res ) + { + std::cerr << "Sorry, " << (*it).c_str() <<" not a gdcm-readable " + << "DICOM / ACR File" <Delete(); + //return 0; + } + std::cout << " ... is readable " << std::endl; + + // We need a gdcm::FileHelper, since we want to load the pixels + GDCM_NAME_SPACE::FileHelper *fh = GDCM_NAME_SPACE::FileHelper::New(file); + + uint8_t *imageData = fh->GetImageData(); + + // Institution name + file->AddAnonymizeElement(0x0008, 0x0080, "*"); + // Patient's name + file->AddAnonymizeElement(0x0010, 0x0010, "*"); + // Patient's ID + file->AddAnonymizeElement( 0x0010, 0x0020,"1515" ); + // Study Instance UID + file->AddAnonymizeElement(0x0020, 0x000d, tempuid ); + // Telephone + file->AddAnonymizeElement(0x0010, 0x2154, "3615" ); + + // Aware user will add here more fields to anonymize here + + // The gdcm::File is modified in memory + + file->AnonymizeFile(); + + + i++; + fh->SetContentType(GDCM_NAME_SPACE::UNMODIFIED_PIXELS_IMAGE); + + fh->WriteDcmExplVR(file->GetFileName() +".ano1" ); + std::cout << i <<" End Anonymize" << std::cout; + file->ClearAnonymizeList(); + file->Delete(); + fh->Delete(); + } +} +#endif +#if defined(USE_GDCM2) +void GimmickView::Anonymize(std::vector i_filenames, int type) +{ +} +#endif +//////////////////////////////////////////////////////////////////////// //void GimmickView::Anonymize(std::vector i_filenames, int type) +//{ +// +// gdcm::FileMetaInformation::SetSourceApplicationEntityTitle( "gdcmanon" ); +// gdcm::Global& g = gdcm::Global::GetInstance(); +// //if( !resourcespath ) +// // { +// // const char *xmlpathenv = getenv("GDCM_RESOURCES_PATH"); +// // if( xmlpathenv ) +// // { +// // // Make sure to look for XML dict in user explicitly specified dir first: +// // xmlpath = xmlpathenv; +// // resourcespath = 1; +// // } +// // } +// // if( resourcespath ) +// // { +// // // xmlpath is set either by the cmd line option or the env var +// // if( !g.Prepend( xmlpath.c_str() ) ) +// // { +// // std::cerr << "Specified Resources Path is not valid: " << xmlpath << std::endl; +// // return 1; +// // } +// // } +// // All set, then load the XML files: +// if( !g.LoadResourcesFiles() ) +// { +// return ; +// } +// const gdcm::Defs &defs = g.GetDefs(); (void)defs; +// if( !rootuid ) +// { +// // only read the env var if no explicit cmd line option +// // maybe there is an env var defined... let's check +// const char *rootuid_env = getenv("GDCM_ROOT_UID"); +// if( rootuid_env ) +// { +// rootuid = 1; +// root = rootuid_env; +// } +// } +// if( rootuid ) +// { +// // root is set either by the cmd line option or the env var +// if( !gdcm::UIDGenerator::IsValid( root.c_str() ) ) +// { +// std::cerr << "specified Root UID is not valid: " << root << std::endl; +// return 1; +// } +// gdcm::UIDGenerator::SetRoot( root.c_str() ); +// } +// +// if(type == 0) // { - //if(type == 0) - //{ - // // Get private key/certificate - // gdcm::CryptographicMessageSyntax cms; - //if( !dumb_mode ) - // { - // if( !GetRSAKeys(cms, rsa_path.c_str(), cert_path.c_str() ) ) - // { - // return 1; - // } - // cms.SetCipherType( ciphertype ); - // } - - //// Setup gdcm::Anonymizer - //gdcm::Anonymizer anon; - //if( !dumb_mode ) - // anon.SetCryptographicMessageSyntax( &cms ); - - //if( dumb_mode ) - // { - // for(unsigned int i = 0; i < nfiles; ++i) - // { - // const char *in = filenames[i].c_str(); - // const char *out = outfilenames[i].c_str(); - // if( !AnonymizeOneFileDumb(anon, in, out, empty_tags, remove_tags, replace_tags_value) ) - // { - // //std::cerr << "Could not anonymize: " << in << std::endl; - // return 1; - // } - // } - // } - //else - // { - // for(unsigned int i = 0; i < nfiles; ++i) - // { - // const char *in = filenames[i].c_str(); - // const char *out = outfilenames[i].c_str(); - // if( !AnonymizeOneFile(anon, in, out) ) - // { - // //std::cerr << "Could not anonymize: " << in << std::endl; - // return 1; - // } - // } - // } -// } \ No newline at end of file +// // Get private key/certificate +// gdcm::CryptographicMessageSyntax cms; +// if( !dumb_mode ) +// { +// if( !GetRSAKeys(cms, rsa_path.c_str(), cert_path.c_str() ) ) +// { +// return 1; +// } +// cms.SetCipherType( ciphertype ); +// } +// +// // Setup gdcm::Anonymizer +// gdcm::Anonymizer anon; +// if( !dumb_mode ) +// anon.SetCryptographicMessageSyntax( &cms ); +// +// if( dumb_mode ) +// { +// for(unsigned int i = 0; i < nfiles; ++i) +// { +// const char *in = filenames[i].c_str(); +// const char *out = outfilenames[i].c_str(); +// if( !AnonymizeOneFileDumb(anon, in, out, empty_tags, remove_tags, replace_tags_value) ) +// { +// //std::cerr << "Could not anonymize: " << in << std::endl; +// return 1; +// } +// } +// } +// //else +// // { +// // for(unsigned int i = 0; i < nfiles; ++i) +// // { +// // const char *in = filenames[i].c_str(); +// // const char *out = outfilenames[i].c_str(); +// // if( !AnonymizeOneFile(anon, in, out) ) +// // { +// // //std::cerr << "Could not anonymize: " << in << std::endl; +// // return 1; +// // } +// // } +// // } +// } +//} +// +} // EO namespace creaImageIO