diff --git a/Modules/US/Testing/mitkUSImageLoggingFilterTest.cpp b/Modules/US/Testing/mitkUSImageLoggingFilterTest.cpp index fd86d898b0..560f43cbf7 100644 --- a/Modules/US/Testing/mitkUSImageLoggingFilterTest.cpp +++ b/Modules/US/Testing/mitkUSImageLoggingFilterTest.cpp @@ -1,178 +1,212 @@ /*=================================================================== 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 "mitkUSImageLoggingFilter.h" #include #include #include #include +#include +#include +#include + #include "mitkImageGenerator.h" #include "itksys/SystemTools.hxx" #include "Poco/File.h" class mitkUSImageLoggingFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkUSImageLoggingFilterTestSuite); MITK_TEST(TestInstantiation); + MITK_TEST(TestSetFileExtension); + MITK_TEST(TestSetWrongFileExtension); MITK_TEST(TestSavingValidTestImage); MITK_TEST(TestSavingAfterMupltipleUpdateCalls); MITK_TEST(TestFilterWithEmptyImages); MITK_TEST(TestFilterWithInvalidPath); MITK_TEST(TestJpgFileExtension); CPPUNIT_TEST_SUITE_END(); private: mitk::USImageLoggingFilter::Pointer m_TestFilter; std::string m_TemporaryTestDirectory; mitk::Image::Pointer m_RandomRestImage1; mitk::Image::Pointer m_RandomRestImage2; mitk::Image::Pointer m_RandomSingleSliceImage; mitk::Image::Pointer m_RealTestImage; public: void setUp() { m_TestFilter = mitk::USImageLoggingFilter::New(); m_TemporaryTestDirectory = mitk::IOUtil::GetTempPath(); m_RandomRestImage1 = mitk::ImageGenerator::GenerateRandomImage(100, 100, 100, 1, 0.2, 0.3, 0.4); m_RandomRestImage2 = mitk::ImageGenerator::GenerateRandomImage(100, 100, 100, 1, 0.2, 0.3, 0.4); m_RandomSingleSliceImage = mitk::ImageGenerator::GenerateRandomImage(100, 100, 1, 1, 0.2, 0.3, 0.4); m_RealTestImage = mitk::IOUtil::LoadImage(GetTestDataFilePath("Pic3D.nrrd")); } void tearDown() { m_TestFilter = NULL; m_RandomRestImage1 = NULL; m_RandomRestImage2 = NULL; m_RealTestImage = NULL; m_RandomSingleSliceImage = NULL; } void TestInstantiation() { CPPUNIT_ASSERT_MESSAGE("Testing instantiation",m_TestFilter.IsNotNull()); } void TestSavingValidTestImage() { //######################## Test with valid test images ################################ m_TestFilter->SetInput(m_RandomRestImage1); m_TestFilter->SetInput("secondImage",m_RandomRestImage2); m_TestFilter->Update(); MITK_TEST_OUTPUT(<<"Tested method Update() with valid data."); std::vector filenames; std::string csvFileName; m_TestFilter->SaveImages(m_TemporaryTestDirectory,filenames,csvFileName); MITK_TEST_OUTPUT(<<"Tested method SaveImages(...)."); CPPUNIT_ASSERT_MESSAGE("Testing if correct number of images was saved",filenames.size() == 1); CPPUNIT_ASSERT_MESSAGE("Testing if image file exists",Poco::File(filenames.at(0).c_str()).exists()); CPPUNIT_ASSERT_MESSAGE("Testing if csv file exists",Poco::File(csvFileName.c_str()).exists()); //clean up std::remove(filenames.at(0).c_str()); std::remove(csvFileName.c_str()); } void TestSavingAfterMupltipleUpdateCalls() { //######################## Test multiple calls of update ################################ m_TestFilter->SetInput(m_RandomRestImage1); m_TestFilter->SetInput("secondImage",m_RandomRestImage2); for(int i=0; i<5; i++) { m_TestFilter->Update(); std::stringstream testmessage; testmessage << "testmessage" << i; m_TestFilter->AddMessageToCurrentImage(testmessage.str()); itksys::SystemTools::Delay(50); } MITK_TEST_OUTPUT(<<"Call Update() 5 times."); std::vector filenames; std::string csvFileName; m_TestFilter->SaveImages(m_TemporaryTestDirectory,filenames,csvFileName); MITK_TEST_OUTPUT(<<"Tested method SaveImages(...)."); CPPUNIT_ASSERT_MESSAGE("Testing if correct number of images was saved",filenames.size() == 5); CPPUNIT_ASSERT_MESSAGE("Testing if file 1 exists",Poco::File(filenames.at(0).c_str()).exists()); CPPUNIT_ASSERT_MESSAGE("Testing if file 2 exists",Poco::File(filenames.at(1).c_str()).exists()); CPPUNIT_ASSERT_MESSAGE("Testing if file 3 exists",Poco::File(filenames.at(2).c_str()).exists()); CPPUNIT_ASSERT_MESSAGE("Testing if file 4 exists",Poco::File(filenames.at(3).c_str()).exists()); CPPUNIT_ASSERT_MESSAGE("Testing if file 5 exists",Poco::File(filenames.at(4).c_str()).exists()); CPPUNIT_ASSERT_MESSAGE("Testing if csv file exists",Poco::File(csvFileName.c_str()).exists()); //clean up for(size_t i=0; iSetInput(testImage); CPPUNIT_ASSERT_MESSAGE("Testing SetInput(...) for first input.",m_TestFilter->GetNumberOfInputs()==1); m_TestFilter->SetInput("secondImage",testImage2); CPPUNIT_ASSERT_MESSAGE("Testing SetInput(...) for second input.",m_TestFilter->GetNumberOfInputs()==2); //images are empty, but update method should not crash CPPUNIT_ASSERT_NO_THROW_MESSAGE("Tested method Update() with invalid data.",m_TestFilter->Update()); } void TestFilterWithInvalidPath() { #ifdef WIN32 std::string filename = "XV:/342INVALID<>"; //invalid filename for windows #else std::string filename = "/dsfdsf:$�$342INVALID"; //invalid filename for linux #endif m_TestFilter->SetInput(m_RealTestImage); m_TestFilter->Update(); CPPUNIT_ASSERT_THROW_MESSAGE("Testing if correct exception if thrown if an invalid path is given.", m_TestFilter->SaveImages(filename), mitk::Exception); } void TestJpgFileExtension() { CPPUNIT_ASSERT_MESSAGE("Testing setting of jpg extension.",m_TestFilter->SetImageFilesExtension(".jpg")); m_TestFilter->SetInput(m_RandomSingleSliceImage); m_TestFilter->Update(); std::vector filenames; std::string csvFileName; m_TestFilter->SaveImages(m_TemporaryTestDirectory,filenames,csvFileName); CPPUNIT_ASSERT_MESSAGE("Testing if correct number of images was saved",filenames.size() == 1); CPPUNIT_ASSERT_MESSAGE("Testing if jpg image file exists",Poco::File(filenames.at(0).c_str()).exists()); CPPUNIT_ASSERT_MESSAGE("Testing if csv file exists",Poco::File(csvFileName.c_str()).exists()); //clean up std::remove(filenames.at(0).c_str()); std::remove(csvFileName.c_str()); } + + void TestSetFileExtension() + { + CPPUNIT_ASSERT_MESSAGE("Testing if PIC extension can be set.",m_TestFilter->SetImageFilesExtension("PIC")); + CPPUNIT_ASSERT_MESSAGE("Testing if bmp extension can be set.",m_TestFilter->SetImageFilesExtension("bmp")); + CPPUNIT_ASSERT_MESSAGE("Testing if gdc extension can be set.",m_TestFilter->SetImageFilesExtension("gdcm")); + CPPUNIT_ASSERT_MESSAGE("Testing if dcm extension can be set.",m_TestFilter->SetImageFilesExtension("dcm")); + CPPUNIT_ASSERT_MESSAGE("Testing if dc3 extension can be set.",m_TestFilter->SetImageFilesExtension("dc3")); + CPPUNIT_ASSERT_MESSAGE("Testing if ima extension can be set.",m_TestFilter->SetImageFilesExtension(".ima")); + CPPUNIT_ASSERT_MESSAGE("Testing if img extension can be set.",m_TestFilter->SetImageFilesExtension("img")); + CPPUNIT_ASSERT_MESSAGE("Testing if gip extension can be set.",m_TestFilter->SetImageFilesExtension("gipl")); + CPPUNIT_ASSERT_MESSAGE("Testing if gipl.gz extension can be set.",m_TestFilter->SetImageFilesExtension(".gipl.gz")); + CPPUNIT_ASSERT_MESSAGE("Testing if jpg extension can be set.",m_TestFilter->SetImageFilesExtension("jpg")); + CPPUNIT_ASSERT_MESSAGE("Testing if jpe extension can be set.",m_TestFilter->SetImageFilesExtension("jpeg")); + CPPUNIT_ASSERT_MESSAGE("Testing if pic extension can be set.",m_TestFilter->SetImageFilesExtension("pic")); + } + + void TestSetWrongFileExtension() + { + + CPPUNIT_ASSERT_MESSAGE("Testing if wrong obj extension is recognized",!m_TestFilter->SetImageFilesExtension("obj ")); + CPPUNIT_ASSERT_MESSAGE("Testing if wrong stl extension is recognized",!m_TestFilter->SetImageFilesExtension("stl ")); + CPPUNIT_ASSERT_MESSAGE("Testing if wrong pvtp extension is recognized",!m_TestFilter->SetImageFilesExtension("pvtp")); + CPPUNIT_ASSERT_MESSAGE("Testing if wrong vtp extension is recognized",!m_TestFilter->SetImageFilesExtension("vtp ")); + CPPUNIT_ASSERT_MESSAGE("Testing if wrong vtk extension is recognized",!m_TestFilter->SetImageFilesExtension("vtk ")); + + } + }; MITK_TEST_SUITE_REGISTRATION(mitkUSImageLoggingFilter) diff --git a/Modules/US/USFilters/mitkUSImageLoggingFilter.cpp b/Modules/US/USFilters/mitkUSImageLoggingFilter.cpp index a15018e652..ad7da4d079 100644 --- a/Modules/US/USFilters/mitkUSImageLoggingFilter.cpp +++ b/Modules/US/USFilters/mitkUSImageLoggingFilter.cpp @@ -1,144 +1,165 @@ /*=================================================================== 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 "mitkUSImageLoggingFilter.h" #include #include #include +#include +#include +#include +#include + + mitk::USImageLoggingFilter::USImageLoggingFilter() : m_SystemTimeClock(RealTimeClock::New()), m_ImageExtension(".nrrd") { } mitk::USImageLoggingFilter::~USImageLoggingFilter() { } void mitk::USImageLoggingFilter::GenerateData() { mitk::Image::ConstPointer inputImage = this->GetInput(); mitk::Image::Pointer outputImage = this->GetOutput(); if(inputImage.IsNull() || inputImage->IsEmpty()) { MITK_WARN << "Input image is not valid. Cannot save image!"; return; } //a clone is needed for a output and to store it. mitk::Image::Pointer inputClone = inputImage->Clone(); //simply redirecy the input to the output //this->SetNumberOfRequiredOutputs(1); //this->SetNthOutput(0, inputClone->Clone()); //outputImage->Graft(inputImage); //this->SetOutput(this->GetInput()); /*if (!this->GetOutput()->IsInitialized()) { this->SetNumberOfRequiredOutputs(1); mitk::Image::Pointer newOutput = mitk::Image::New(); this->SetNthOutput(0, newOutput); } memcpy(this->GetOutput(),this->GetInput());*/ //this->SetNthOutput(0,inputImage.); //this->AllocateOutputs(); //this->GraftOutput(inputClone); /* if (!this->GetOutput()->IsInitialized()) { mitk::Image::Pointer newOutput = mitk::Image::New(); this->SetNthOutput(0, newOutput); } this->GetOutput()Graft(this->GetInput()); */ m_LoggedImages.push_back(inputClone); m_LoggedMITKSystemTimes.push_back(m_SystemTimeClock->GetCurrentStamp()); } void mitk::USImageLoggingFilter::AddMessageToCurrentImage(std::string message) { m_LoggedMessages.insert(std::make_pair(static_cast(m_LoggedImages.size()-1),message)); } void mitk::USImageLoggingFilter::SaveImages(std::string path) { std::vector dummy1; std::string dummy2; this->SaveImages(path,dummy1,dummy2); } void mitk::USImageLoggingFilter::SaveImages(std::string path, std::vector& filenames, std::string& csvFileName) { filenames = std::vector(); //test if path is valid Poco::Path testPath(path); if(!testPath.isDirectory()) { mitkThrow() << "Attemting to write to directory " << path << " which is not valid! Aborting!"; } //generate a unique ID which is used as part of the filenames, so we avoid to overwrite old files by mistake. mitk::UIDGenerator myGen = mitk::UIDGenerator("",5); std::string uniqueID = myGen.GetUID(); //first: write the images for(size_t i=0; i::iterator it = m_LoggedMessages.find(i); if (m_LoggedMessages.empty() || (it == m_LoggedMessages.end())) os << filenames.at(i) << ";" << m_LoggedMITKSystemTimes.at(i) << ";" << "" << "\n"; else os << filenames.at(i) << ";" << m_LoggedMITKSystemTimes.at(i) << ";" << it->second << "\n"; } //close file fb.close(); } bool mitk::USImageLoggingFilter::SetImageFilesExtension(std::string extension) { - m_ImageExtension = extension; - return true; + if(extension.compare(0,1,".") == 0) + extension = extension.substr(1,extension.size()-1); + + CoreServicePointer mimeTypeProvider(CoreServices::GetMimeTypeProvider()); + + std::vector mimeTypes = mimeTypeProvider->GetMimeTypesForCategory(IOMimeTypes::CATEGORY_IMAGES()); + + for(std::vector::size_type i = 0 ; i< mimeTypes.size() ; ++i) + { + std::vector extensions = mimeTypes[i].GetExtensions(); + if (std::find(extensions.begin(), extensions.end(), extension) != extensions.end()) + { + m_ImageExtension = "."+extension; + return true; + } + } + return false; } diff --git a/Modules/US/USFilters/mitkUSImageLoggingFilter.h b/Modules/US/USFilters/mitkUSImageLoggingFilter.h index debb95bb60..23d616a18b 100644 --- a/Modules/US/USFilters/mitkUSImageLoggingFilter.h +++ b/Modules/US/USFilters/mitkUSImageLoggingFilter.h @@ -1,95 +1,94 @@ /*=================================================================== 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 MITKUSImageLoggingFiler_H_HEADER_INCLUDED_ #define MITKUSImageLoggingFiler_H_HEADER_INCLUDED_ // MITK #include #include #include namespace mitk { /** An object of this class is a filter which saves/logs a clone of the current image whenever * Update() is called. Additionally a timestamp of this image is saved. Optionally you can * add messages. All data (images, timestamps and messages) is written to the harddisc when * the method SaveImages(...) is called. * * Caution: only supports logging of one input at the moment, multiple inputs are ignored! * * \ingroup US */ class MitkUS_EXPORT USImageLoggingFilter : public mitk::ImageToImageFilter { public: mitkClassMacro(USImageLoggingFilter, mitk::ImageToImageFilter); itkNewMacro(USImageLoggingFilter); /** This method is internally called by the Update() mechanism of the pipeline. Don't call it directly. */ virtual void GenerateData(); /** Adds a message to the current (last logged) image. This message is internally stored and written to the * harddisc when SaveImages(...) is called. * @param message The string which contains the message which is logged to the current image */ void AddMessageToCurrentImage(std::string message); /** Saves all logged data to the given path. Every image is written to a separate image file. * Additionaly a csv file containing a list of all images together with timestamps and messages is saved. * For one call of this method all files will start with a unique number to avoid overwrite of old files. * @param[in] path Should contain a valid path were all logging data will be stored. * @param[out] imageFilenames Returns a list of all images filenames which were stored to the harddisc. * @param[out] csvFileName Returns the filename of the csv list with the timestamps and the messages. * @throw mitk::Exception Throws an exception if there is a problem during writing the images. E.g., * if the path is not valid / not writable. */ void SaveImages(std::string path, std::vector& imageFilenames, std::string& csvFileName); /** Saves all logged data to the given path. Every image is written to a separate image file. * Additionaly a csv file containing a list of all images together with timestamps and messages is saved. * For one call of this method all files will start with a unique number to avoid overwrite of old files. * @param[in] path Should contain a valid path were all logging data will be stored. * @throw mitk::Exception Throws an exception if there is a problem during writing the images. E.g., * if the path is not valid / not writable. */ void SaveImages(std::string path); /** Sets the extension of the output images which alse defines the file type. E.g., ".nrrd" or ".jpg". * ".nrrd" is default. * @return Returns true if the file extension was successfully set which means it is supported. False if not. - * @deprecated_since{next_release} */ - DEPRECATED(bool SetImageFilesExtension(std::string extension)); + bool SetImageFilesExtension(std::string extension); protected: USImageLoggingFilter(); virtual ~USImageLoggingFilter(); typedef std::vector ImageCollection; mitk::RealTimeClock::Pointer m_SystemTimeClock; ///< system time clock for system time tag //members for logging ImageCollection m_LoggedImages; ///< An image collection for every input. The string identifies the input. std::map m_LoggedMessages; ///< (Optional) messages for every logged image std::vector m_LoggedMITKSystemTimes; ///< Logged system times for every logged image std::string m_ImageExtension; ///< stores the image extension, default is ".nrrd" }; } // namespace mitk #endif /* MITKUSImageSource_H_HEADER_INCLUDED_ */