/* # # File : itkSTMS_ImageSequenceToTemporalSet.txx # ( C++ header file - STMS ) # # Description : STMS lib that implements the STMS filter and clustering. # This file is a part of the STMS Library project. # ( https://www.creatis.insa-lyon.fr/site7/fr/realisations ) # # [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H., # « Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification », # Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015. # # Copyright : Thomas GRENIER - Simon MURE # ( https://www.creatis.insa-lyon.fr/~grenier/ ) # # License : CeCILL C # ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt ) # # This software is governed by the CeCILL 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 # license as circulated by CEA, CNRS and INRIA at the following URL # "http://www.cecill.info". # # 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. # # In this respect, the user's attention is drawn to the risks associated # with loading, using, modifying and/or developing or reproducing the # software by the user in light of its specific status of free software, # that may mean that it is complicated to manipulate, and that also # therefore means that it is reserved for developers and experienced # professionals having in-depth computer knowledge. Users are therefore # encouraged to load and test the software's suitability as regards their # requirements in conditions enabling the security of their systems and/or # data to be ensured and, more generally, to use and operate it in the # same conditions as regards security. # # The fact that you are presently reading this means that you have had # knowledge of the CeCILL license and that you accept its terms. # */ /* Please don't forget to cite our work : @article {MURE-15a, title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification}, journal = {Pattern Recognition Letters}, volume = {68, Part 1}, year = {2015}, pages = {48 - 55}, issn = {0167-8655}, doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021}, url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305}, author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin} } */ #ifndef itkSTMS_ImageSequenceToTemporalSet_txx #define itkSTMS_ImageSequenceToTemporalSet_txx #include #include "itkSTMS_ImageSequenceToTemporalSet.h" #include "itkSTMS_XMLFileParser.h" #include "itkSTMS_ArgumentsAnalysis.h" #include "itkFancyString.h" namespace itkSTMS { template < class ImageType, class MaskImageType > itkSTMS_ImageSequenceToTemporalSet < ImageType, MaskImageType > ::itkSTMS_ImageSequenceToTemporalSet( ParamsAnalysisOutputType* stmsParameters ) { // Get experiments parameters given by the user this->stmsParameters = stmsParameters; // XML file parsing xmlParser = new itkSTMS::itkSTMS_XMLFileParser(); xmlParser->SetFileName( this->stmsParameters->expDescription ); xmlParser->Update(); expDescription = xmlParser->GetXMLParams(); // If a mask image is specified ==> instanciation of a mask iterator (region with the highest value in the mask) if( expDescription->maskImage != "null" ) { mask = MaskImageType::New(); mReader = MaskReaderType::New(); MinMaxCalculator = MinMaxCalculatorType::New(); maskPath = expDescription->maskImage; //expDescription->experimentPath+expDescription->inputFolder+expDescription->maskImage+expDescription->imageExtension; mReader->SetFileName( maskPath ); mReader->Update(); mask = mReader->GetOutput(); MinMaxCalculator->SetImage( mask ); MinMaxCalculator->ComputeMaximum(); maskValue = (MaskPixelType)MinMaxCalculator->GetMaximum(); mIt = MaskIteratorType( mask, mask->GetLargestPossibleRegion() ); //->GetBufferedRegion() ); } } template < class ImageType, class MaskImageType > void itkSTMS_ImageSequenceToTemporalSet< ImageType, MaskImageType > ::GenerateDataSets() { bool first = true; std::string str; IndexType idx; // Preprocessing of the whole image sequence // stmsParameters->startTimePoint for( unsigned int i=1 ; i<=stmsParameters->numTimePoints - stmsParameters->startTimePoint + 1 ; ++i ) { idx = 0; char buffer[6]; // int n = 0; // used to debug sprintf : n = sprintf( ... if( sizeof(STMS_NUMBERING_FORM_ONE) == 6 ) sprintf (buffer, "%05d", i + stmsParameters->startTimePoint - 1); if( sizeof(STMS_NUMBERING_FORM_ONE) == 5 ) sprintf (buffer, "%04d", i + stmsParameters->startTimePoint - 1); if( sizeof(STMS_NUMBERING_FORM_ONE) == 4 ) sprintf (buffer, "%03d", i + stmsParameters->startTimePoint - 1); if( sizeof(STMS_NUMBERING_FORM_ONE) == 3 ) sprintf (buffer, "%02d", i + stmsParameters->startTimePoint - 1); if( sizeof(STMS_NUMBERING_FORM_ONE) == 2 ) sprintf (buffer, "%01d", i + stmsParameters->startTimePoint - 1); std::string imagePath = expDescription->experimentPath+expDescription->inputFolder+expDescription->inputCommonRoot+buffer+expDescription->imageExtension; ImagePointer image = ImageType::New(); ReaderPointer reader = itk::ImageFileReader< ImageType >::New(); reader->SetFileName( imagePath ); reader->Update(); image = reader->GetOutput(); IteratorType it( image, image->GetLargestPossibleRegion() ); SizeType Size = image->GetLargestPossibleRegion().GetSize(); // If there is no mask image specified, all the pixels are extracted if( expDescription->maskImage == "null" ) { // Only the range values have to be extracted at each time-point. The others need to be extracted just one time. if( first ) { // Containers initialisation unsigned int numSamples = (unsigned int)Size[0]; for( unsigned int j=1 ; jdim ; ++j ) numSamples *= (unsigned int)Size[j]; indexSet = IndexSampleSetType( numSamples, 0 ); classSet = IndexSampleSetType( numSamples, 0 ); mergingSet = IndexSampleSetType( numSamples, 0 ); weightsSet = IndexSampleSetType( numSamples, 1 ); spatialSet = SpatialSampleSetType( numSamples, SpatialVectorType(stmsParameters->dim, 0)); rangeSet = RangeSampleSetType ( numSamples, RangeVectorType(stmsParameters->numTimePoints - stmsParameters->startTimePoint + 1, 0) ); } // Samples extraction it.GoToBegin(); while( !it.IsAtEnd() ){ if( first ){ indexSet[idx] = idx; classSet[idx] = idx+1; for( unsigned int j=0 ; jdim ; ++j ) spatialSet[idx][j] = (SpatialType)( it.GetIndex()[j]/stmsParameters->spScales[j] ); } rangeSet[idx++][i-1] = (PixelType)(it.Get()/stmsParameters->rScale); ++it; } if( first ) first = false; } // If a mask is specified, just the characteristics of the pixels equal to maskValue in the mask image are extracted else { // In this case the number of samples is not known in advance if( first ) { indexSet = IndexSampleSetType(); classSet = IndexSampleSetType(); mergingSet = IndexSampleSetType(); weightsSet = IndexSampleSetType(); spatialSet = SpatialSampleSetType(); rangeSet = RangeSampleSetType(); indexSet.reserve ( Size[0]*Size[1] ); classSet.reserve ( Size[0]*Size[1] ); mergingSet.reserve( Size[0]*Size[1] ); weightsSet.reserve( Size[0]*Size[1] ); spatialSet.reserve( Size[0]*Size[1] ); rangeSet.reserve ( Size[0]*Size[1] ); } // Samples extraction mIt.GoToBegin(); it.GoToBegin(); while( !mIt.IsAtEnd() ) { if(mIt.Get() == maskValue) { if( first ) { SpatialVectorType spComp = SpatialVectorType(stmsParameters->dim, 0); for( unsigned int j=0 ; jdim ; ++j ) spComp[j] = (SpatialType)( it.GetIndex()[j]/stmsParameters->spScales[j] ); indexSet.push_back ( idx ); classSet.push_back ( ++idx ); mergingSet.push_back( 0 ); weightsSet.push_back( 1 ); spatialSet.push_back( spComp ); rangeSet.push_back( RangeVectorType(stmsParameters->numTimePoints - stmsParameters->startTimePoint + 1, (PixelType)(it.Get()/stmsParameters->rScale)) ); } else rangeSet[idx++][i-1] = (PixelType)(it.Get()/stmsParameters->rScale); } ++mIt; ++it; } if( first ) first = false; } } } } // end of namespace itkSTMS #endif