diff --git a/Modules/OpenCVVideoSupport/Testing/CMakeLists.txt b/Modules/OpenCVVideoSupport/Testing/CMakeLists.txt index 153cd81e2e..8d43ce4a4d 100644 --- a/Modules/OpenCVVideoSupport/Testing/CMakeLists.txt +++ b/Modules/OpenCVVideoSupport/Testing/CMakeLists.txt @@ -1 +1,10 @@ MITK_CREATE_MODULE_TESTS() + +IF(BUILD_TESTING AND MODULE_IS_ENABLED) + mitkAddCustomModuleTest("mitkOpenCVMitkConversionTest" "mitkOpenCVMitkConversionTest" + "${MITK_DATA_DIR}/ToF-Data/Kinect_LiverPhantom_DistanceImage.nrrd" + "${MITK_DATA_DIR}/ToF-Data/Kinect_LiverPhantom_RGBImage.nrrd" + "${MITK_DATA_DIR}/Png2D-bw.png" + "${MITK_DATA_DIR}/NrrdWritingTestImage.jpg" + ) +ENDIF(BUILD_TESTING AND MODULE_IS_ENABLED) \ No newline at end of file diff --git a/Modules/OpenCVVideoSupport/Testing/files.cmake b/Modules/OpenCVVideoSupport/Testing/files.cmake index 072396b7ac..396c39d368 100644 --- a/Modules/OpenCVVideoSupport/Testing/files.cmake +++ b/Modules/OpenCVVideoSupport/Testing/files.cmake @@ -1,3 +1,5 @@ -set(MODULE_TESTS - mitkOpenCVMitkConversionTest.cpp +SET(MODULE_TESTS ) +SET(MODULE_CUSTOM_TESTS + mitkOpenCVMitkConversionTest.cpp +) \ No newline at end of file diff --git a/Modules/OpenCVVideoSupport/Testing/mitkOpenCVMitkConversionTest.cpp b/Modules/OpenCVVideoSupport/Testing/mitkOpenCVMitkConversionTest.cpp index 92b18df971..c5ce82926b 100644 --- a/Modules/OpenCVVideoSupport/Testing/mitkOpenCVMitkConversionTest.cpp +++ b/Modules/OpenCVVideoSupport/Testing/mitkOpenCVMitkConversionTest.cpp @@ -1,145 +1,305 @@ /*=================================================================== 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. ===================================================================*/ +// mitk includes #include "mitkImageToOpenCVImageFilter.h" #include "mitkOpenCVToMitkImageFilter.h" #include #include -#include -#include -#include #include #include +#include "mitkItkImageFileReader.h" +#include "mitkImageReadAccessor.h" +#include "mitkImageSliceSelector.h" + +// itk includes +#include + +#include +#include // define test pixel indexes and intensities and other values typedef itk::RGBPixel< unsigned char > TestUCRGBPixelType; cv::Size testImageSize; cv::Point pos1; cv::Point pos2; cv::Point pos3; cv::Vec3b color1; cv::Vec3b color2; cv::Vec3b color3; uchar greyValue1; uchar greyValue2; uchar greyValue3; -template -void ComparePixels( itk::Image,VImageDimension>* image ) -{ - - - typedef itk::RGBPixel PixelType; - typedef itk::Image ImageType; - - typename ImageType::IndexType pixelIndex; - pixelIndex[0] = pos1.x; - pixelIndex[1] = pos1.y; - PixelType onePixel = image->GetPixel( pixelIndex ); - - MITK_TEST_CONDITION( color1[0] == onePixel.GetBlue(), "Testing if blue value (= " << static_cast(color1[0]) << ") at postion " - << pos1.x << ", " << pos1.y << " in OpenCV image is " - << "equals the blue value (= " << static_cast(onePixel.GetBlue()) << ")" - << " in the generated mitk image"); - - - pixelIndex[0] = pos2.x; - pixelIndex[1] = pos2.y; - onePixel = image->GetPixel( pixelIndex ); - MITK_TEST_CONDITION( color2[1] == onePixel.GetGreen(), "Testing if green value (= " << static_cast(color2[1]) << ") at postion " - << pos2.x << ", " << pos2.y << " in OpenCV image is " - << "equals the green value (= " << static_cast(onePixel.GetGreen()) << ")" - << " in the generated mitk image"); +/*! Documentation +* Test for image conversion of OpenCV images and mitk::Images. It tests the classes +* OpenCVToMitkImageFilter and ImageToOpenCVImageFilter +*/ - pixelIndex[0] = pos3.x; - pixelIndex[1] = pos3.y; - onePixel = image->GetPixel( pixelIndex ); +// Some declarations +template +void ComparePixels( itk::Image,VImageDimension>* image ); - MITK_TEST_CONDITION( color3[2] == onePixel.GetRed(), "Testing if red value (= " << static_cast(color3[2]) << ") at postion " - << pos3.x << ", " << pos3.y << " in OpenCV image is " - << "equals the red value (= " << static_cast(onePixel.GetRed()) << ")" - << " in the generated mitk image"); +void ReadImageDataAndConvertForthAndBack(std::string imageFileName); -} +void ConvertIplImageForthAndBack(mitk::Image::Pointer inputForCVMat, std::string imageFileName); +void ConvertCVMatForthAndBack(mitk::Image::Pointer inputForCVMat, std::string imageFileName); +// Begin the test for mitkImage to OpenCV image conversion and back. int mitkOpenCVMitkConversionTest(int argc, char* argv[]) { MITK_TEST_BEGIN("ImageToOpenCVImageFilter") + // the first part of this test checks the conversion of a cv::Mat style OpenCV image. + + // we build an cv::Mat image MITK_INFO << "setting test values"; testImageSize = cv::Size(11,11); pos1 = cv::Point(0,0); pos2 = cv::Point(5,5); pos3 = cv::Point(10,10); color1 = cv::Vec3b(50,0,0); color2 = cv::Vec3b(0,128,0); color3 = cv::Vec3b(0,0,255); greyValue1 = 0; greyValue2 = 128; greyValue3 = 255; MITK_INFO << "generating test OpenCV image (RGB)"; cv::Mat testRGBImage = cv::Mat::zeros( testImageSize, CV_8UC3 ); + // generate some test intensity values testRGBImage.at(pos1)= color1; testRGBImage.at(pos2)= color2; testRGBImage.at(pos3)= color3; //cv::namedWindow("debug", CV_WINDOW_FREERATIO ); //cv::imshow("debug", testRGBImage.clone()); //cv::waitKey(0); + // convert it to a mitk::Image MITK_INFO << "converting OpenCV test image to mitk image and comparing scalar rgb values"; mitk::OpenCVToMitkImageFilter::Pointer openCvToMitkFilter = mitk::OpenCVToMitkImageFilter::New(); openCvToMitkFilter->SetOpenCVMat( testRGBImage ); openCvToMitkFilter->Update(); mitk::Image::Pointer mitkImage = openCvToMitkFilter->GetOutput(); AccessFixedTypeByItk(mitkImage.GetPointer(), ComparePixels, - (itk::RGBPixel), // rgb image - (2) ); - + (itk::RGBPixel), // rgb image + (2) ); + // convert it back to OpenCV image MITK_INFO << "converting mitk image to OpenCV image and comparing scalar rgb values"; mitk::ImageToOpenCVImageFilter::Pointer mitkToOpenCv = mitk::ImageToOpenCVImageFilter::New(); mitkToOpenCv->SetImage( mitkImage ); cv::Mat openCvImage = mitkToOpenCv->GetOpenCVMat(); + // and test equality of the sentinel pixel cv::Vec3b convertedColor1 = openCvImage.at(pos1); cv::Vec3b convertedColor2 = openCvImage.at(pos2); cv::Vec3b convertedColor3 = openCvImage.at(pos3); MITK_TEST_CONDITION( color1 == convertedColor1, "Testing if initially created color values " << static_cast( color1[0] ) << ", " << static_cast( color1[1] ) << ", " << static_cast( color1[2] ) << " matches the color values " << static_cast( convertedColor1[0] ) << ", " << static_cast( convertedColor1[1] ) << ", " << static_cast( convertedColor1[2] ) << " at the same position " << pos1.x << ", " << pos1.y << " in the back converted OpenCV image" ) MITK_TEST_CONDITION( color2 == convertedColor2, "Testing if initially created color values " << static_cast( color2[0] ) << ", " << static_cast( color2[1] ) << ", " << static_cast( color2[2] ) << " matches the color values " << static_cast( convertedColor2[0] ) << ", " << static_cast( convertedColor2[1] ) << ", " << static_cast( convertedColor2[2] ) << " at the same position " << pos2.x << ", " << pos2.y << " in the back converted OpenCV image" ) MITK_TEST_CONDITION( color3 == convertedColor3, "Testing if initially created color values " << static_cast( color3[0] ) << ", " << static_cast( color3[1] ) << ", " << static_cast( color3[2] ) << " matches the color values " << static_cast( convertedColor3[0] ) << ", " << static_cast( convertedColor3[1] ) << ", " << static_cast( convertedColor3[2] ) << " at the same position " << pos3.x << ", " << pos3.y << " in the back converted OpenCV image" ) + // the second part of this test checks the conversion of mitk::Images to Ipl images and cv::Mat and back. + for(unsigned int i = 1; i < argc; ++i ) + { + ReadImageDataAndConvertForthAndBack(argv[i]); + } + MITK_TEST_END(); +} + +template +void ComparePixels( itk::Image,VImageDimension>* image ) +{ + + typedef itk::RGBPixel PixelType; + typedef itk::Image ImageType; + + typename ImageType::IndexType pixelIndex; + pixelIndex[0] = pos1.x; + pixelIndex[1] = pos1.y; + PixelType onePixel = image->GetPixel( pixelIndex ); + + MITK_TEST_CONDITION( color1[0] == onePixel.GetBlue(), "Testing if blue value (= " << static_cast(color1[0]) << ") at postion " + << pos1.x << ", " << pos1.y << " in OpenCV image is " + << "equals the blue value (= " << static_cast(onePixel.GetBlue()) << ")" + << " in the generated mitk image"); + + + pixelIndex[0] = pos2.x; + pixelIndex[1] = pos2.y; + onePixel = image->GetPixel( pixelIndex ); + MITK_TEST_CONDITION( color2[1] == onePixel.GetGreen(), "Testing if green value (= " << static_cast(color2[1]) << ") at postion " + << pos2.x << ", " << pos2.y << " in OpenCV image is " + << "equals the green value (= " << static_cast(onePixel.GetGreen()) << ")" + << " in the generated mitk image"); + + + pixelIndex[0] = pos3.x; + pixelIndex[1] = pos3.y; + onePixel = image->GetPixel( pixelIndex ); + + MITK_TEST_CONDITION( color3[2] == onePixel.GetRed(), "Testing if red value (= " << static_cast(color3[2]) << ") at postion " + << pos3.x << ", " << pos3.y << " in OpenCV image is " + << "equals the red value (= " << static_cast(onePixel.GetRed()) << ")" + << " in the generated mitk image"); + +} + +void ReadImageDataAndConvertForthAndBack(std::string imageFileName) +{ + // first we load an mitk::Image from the data repository + mitk::ItkImageFileReader::Pointer reader = mitk::ItkImageFileReader::New(); + reader->SetFileName(imageFileName); + reader->Update(); + mitk::Image::Pointer mitkTestImage = reader->GetOutput(); + + // some format checking + mitk::Image::Pointer resultImg = NULL; + if( mitkTestImage->GetDimension() <= 3 ) + { + if( mitkTestImage->GetDimension() > 2 && mitkTestImage->GetDimension(2) == 1 ) + { + mitk::ImageSliceSelector::Pointer sliceSelector = mitk::ImageSliceSelector::New(); + sliceSelector->SetInput(mitkTestImage); + sliceSelector->SetSliceNr(0); + sliceSelector->Update(); + resultImg = sliceSelector->GetOutput()->Clone(); + } + else if(mitkTestImage->GetDimension() < 3) + { + resultImg = mitkTestImage; + } + else + { + return; // 3D images are not supported, except with just one slice. + } + } + else + { + return; // 4D images are not supported! + } + + ConvertIplImageForthAndBack(resultImg, imageFileName); + ConvertCVMatForthAndBack(resultImg, imageFileName); } +void ConvertCVMatForthAndBack(mitk::Image::Pointer inputForCVMat, std::string imageFileName) +{ + // now we convert it to OpenCV IplImage + mitk::ImageToOpenCVImageFilter::Pointer toOCvConverter = mitk::ImageToOpenCVImageFilter::New(); + toOCvConverter->SetImage(inputForCVMat); + cv::Mat cvmatTestImage = toOCvConverter->GetOpenCVMat(); + + MITK_TEST_CONDITION_REQUIRED( &cvmatTestImage != NULL, "Conversion to cv::Mat successful!"); + + //// temp visualization of IplImage + //cv::Mat matData = cv::Mat(iplTestImage, true); + //double minVal, maxVal; + //cv::minMaxLoc(matData, &minVal, &maxVal); + //cv::Mat uCCvImage; + //matData.convertTo(uCCvImage,CV_8U, 255.0/(maxVal - minVal), -minVal ); + //cv::namedWindow("IplImage", CV_WINDOW_AUTOSIZE); + //cv::imshow("IplImage", uCCvImage); + //cv::waitKey(10000); + //cv::destroyWindow("IplImage"); + //// end temp visualization of IplImage + + mitk::OpenCVToMitkImageFilter::Pointer toMitkConverter = mitk::OpenCVToMitkImageFilter::New(); + toMitkConverter->SetOpenCVMat(cvmatTestImage); + toMitkConverter->Update(); + + // initialize the image with the input image, since we want to test equality and OpenCV does not feature geometries and spacing + mitk::Image::Pointer result = inputForCVMat->Clone(); + mitk::ImageReadAccessor resultAcc(toMitkConverter->GetOutput(), toMitkConverter->GetOutput()->GetSliceData()); + result->SetImportSlice(const_cast(resultAcc.GetData())); + + //// temp visualization of IplImage + //mitk::ImageToOpenCVImageFilter::Pointer openCvImageCon = mitk::ImageToOpenCVImageFilter::New(); + //openCvImageCon->SetImage(result); + //cv::Mat cvImage2 = cv::Mat(openCvImageCon->GetOpenCVImage(), true); + //double minVal, maxVal; + //cv::minMaxLoc(cvImage2, &minVal, &maxVal); + //cv::Mat uCCvImage; + //cvImage2.convertTo(uCCvImage,CV_8U, 255.0/(maxVal - minVal), -minVal ); + //cv::namedWindow("IplImage", CV_WINDOW_AUTOSIZE); + //cv::imshow("IplImage", uCCvImage); + //cv::waitKey(10000); + //cv::destroyWindow("IplImage"); + //// end temp visualization of IplImage + + if( result->GetPixelType().GetNumberOfComponents() == 1 ) + { + MITK_TEST_EQUAL( result, inputForCVMat, "Testing equality of input and output image of cv::Mat conversion for " << imageFileName ); + } + else if( result->GetPixelType().GetNumberOfComponents() == 3 ) + { + MITK_WARN << "Implement MITK_TEST_EQUAL functionality for three component images!"; + } + else + { + MITK_WARN << "Unhandled number of components used to test equality, please enhance test!"; + } +} +void ConvertIplImageForthAndBack(mitk::Image::Pointer inputForIpl, std::string imageFileName) +{ + // now we convert it to OpenCV IplImage + mitk::ImageToOpenCVImageFilter::Pointer toOCvConverter = mitk::ImageToOpenCVImageFilter::New(); + toOCvConverter->SetImage(inputForIpl); + IplImage* iplTestImage = toOCvConverter->GetOpenCVImage(); + + MITK_TEST_CONDITION_REQUIRED( iplTestImage != NULL, "Conversion to OpenCv IplImage successful!"); + + mitk::OpenCVToMitkImageFilter::Pointer toMitkConverter = mitk::OpenCVToMitkImageFilter::New(); + toMitkConverter->SetOpenCVImage(iplTestImage); + toMitkConverter->Update(); + + // initialize the image with the input image, since we want to test equality and OpenCV does not feature geometries and spacing + mitk::Image::Pointer result = inputForIpl->Clone(); + mitk::ImageReadAccessor resultAcc(toMitkConverter->GetOutput(), toMitkConverter->GetOutput()->GetSliceData()); + result->SetImportSlice(const_cast(resultAcc.GetData())); + + if( result->GetPixelType().GetNumberOfComponents() == 1 ) + { + MITK_TEST_EQUAL( result, inputForIpl, "Testing equality of input and output image of IplImage conversion for " << imageFileName ); + } + else if( result->GetPixelType().GetNumberOfComponents() == 3 ) + { + MITK_WARN << "Implement MITK_TEST_EQUAL functionality for three component images!"; + } + else + { + MITK_WARN << "Unhandled number of components used to test equality, please enhance test!"; + } +} \ No newline at end of file diff --git a/Modules/OpenCVVideoSupport/mitkImageToOpenCVImageFilter.cpp b/Modules/OpenCVVideoSupport/mitkImageToOpenCVImageFilter.cpp index e26bfa3cfc..7ef273b76c 100644 --- a/Modules/OpenCVVideoSupport/mitkImageToOpenCVImageFilter.cpp +++ b/Modules/OpenCVVideoSupport/mitkImageToOpenCVImageFilter.cpp @@ -1,92 +1,101 @@ /*=================================================================== 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 "mitkImageToOpenCVImageFilter.h" #include #include #include -mitk::ImageToOpenCVImageFilter::ImageToOpenCVImageFilter() -: m_OpenCVImage(0) -{ -} - -mitk::ImageToOpenCVImageFilter::~ImageToOpenCVImageFilter() -{ - m_OpenCVImage = 0; -} - -bool mitk::ImageToOpenCVImageFilter::CheckImage( mitk::Image* image ) -{ - if(image == 0) +namespace mitk{ + + ImageToOpenCVImageFilter::ImageToOpenCVImageFilter() + : m_OpenCVImage(0) { - MITK_WARN << "MITK Image is 0"; - return false; } - if(image->GetDimension() != 2) + + ImageToOpenCVImageFilter::~ImageToOpenCVImageFilter() { - MITK_WARN << "Only 2D Images allowed"; - return false; + m_OpenCVImage = 0; } - return true; -} -IplImage* mitk::ImageToOpenCVImageFilter::GetOpenCVImage() -{ - m_OpenCVImage = 0; - if(!this->CheckImage( m_Image )) - return 0; + void ImageToOpenCVImageFilter::SetImage( Image* _Image ) + { + m_Image = _Image; + } + + + bool ImageToOpenCVImageFilter::CheckImage( Image* image ) + { + if(image == 0) + { + MITK_WARN << "MITK Image is 0"; + return false; + } + if(image->GetDimension() > 2 ) + { + MITK_WARN << "Only 2D Images allowed"; + return false; + } + return true; + } + + IplImage* ImageToOpenCVImageFilter::GetOpenCVImage() + { + + if(!this->CheckImage( m_Image )) + return 0; + + m_OpenCVImage = (0); try { AccessFixedTypeByItk(m_Image.GetPointer(), ItkImageProcessing, - MITK_ACCESSBYITK_PIXEL_TYPES_SEQ // gray image - (UCRGBPixelType)(USRGBPixelType)(FloatRGBPixelType)(DoubleRGBPixelType), // rgb image - (2) // dimensions - ) + MITK_ACCESSBYITK_PIXEL_TYPES_SEQ // gray image + (UCRGBPixelType)(USRGBPixelType)(FloatRGBPixelType)(DoubleRGBPixelType), // rgb image + (2) // dimensions + ) } catch (const AccessByItkException& e) { std::cout << "Caught exception [from AccessFixedTypeByItk]: \n" << e.what() << "\n"; return 0; } + return m_OpenCVImage; + } - return m_OpenCVImage; -} - -cv::Mat mitk::ImageToOpenCVImageFilter::GetOpenCVMat() -{ + cv::Mat ImageToOpenCVImageFilter::GetOpenCVMat() + { IplImage* img = this->GetOpenCVImage(); - //cvNamedWindow("debug2", CV_WINDOW_FREERATIO); - //cvShowImage("debug2", img); - //cv::waitKey(0); + cv::Mat mat; if( img ) { - // do not copy data, then release just the header - mat = cv::Mat ( img, false ); - cvReleaseImageHeader( &img ); + // do not copy data, then release just the header + mat = cv::Mat ( img, false ); + cvReleaseImageHeader( &img ); } return mat; -} + } + + template + void ImageToOpenCVImageFilter::ItkImageProcessing( itk::Image* image ) + { + m_OpenCVImage = itk::OpenCVImageBridge::ITKImageToIplImage(image); + } -void mitk::ImageToOpenCVImageFilter::SetImage( mitk::Image* _Image ) -{ -// if(m_Image == _Image) return; - m_Image = _Image; -} +} // end namespace mitk \ No newline at end of file diff --git a/Modules/OpenCVVideoSupport/mitkImageToOpenCVImageFilter.h b/Modules/OpenCVVideoSupport/mitkImageToOpenCVImageFilter.h index 3f82f25969..798f8087e3 100644 --- a/Modules/OpenCVVideoSupport/mitkImageToOpenCVImageFilter.h +++ b/Modules/OpenCVVideoSupport/mitkImageToOpenCVImageFilter.h @@ -1,97 +1,91 @@ /*=================================================================== 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 mitkImageToOpenCVImageFilter_h #define mitkImageToOpenCVImageFilter_h #include #include #include #include #include namespace mitk { /// /// \brief A pseudo-Filter for creating OpenCV images from MITK images with the option of copying data or referencing it /// class MITK_OPENCVVIDEOSUPPORT_EXPORT ImageToOpenCVImageFilter : public itk::Object { public: typedef itk::RGBPixel< unsigned char > UCRGBPixelType; typedef itk::RGBPixel< unsigned short > USRGBPixelType; typedef itk::RGBPixel< float > FloatRGBPixelType; typedef itk::RGBPixel< double > DoubleRGBPixelType; mitkClassMacro(ImageToOpenCVImageFilter, itk::Object); itkNewMacro(ImageToOpenCVImageFilter); /// /// \brief set the input MITK image /// void SetImage( mitk::Image* _Image ); /// /// \brief get the input MITK image /// itkGetMacro(Image, mitk::Image*); /// /// \brief get the input MITK image /// bool CheckImage(mitk::Image* image); /// /// RUNS the conversion and returns the produced OpenCVImage. /// !!!ATTENTION!!! Do not forget to release this image again with cvReleaseImage(). /// \return the produced OpenCVImage or 0 if an error occured! /// IplImage* GetOpenCVImage(); /// /// RUNS the conversion and returns the produced image as cv::Mat. /// \return the produced OpenCVImage or an empty image if an error occured /// cv::Mat GetOpenCVMat(); protected: /// /// the actual templated conversion method /// template void ItkImageProcessing( itk::Image* image ); ImageToOpenCVImageFilter(); ~ImageToOpenCVImageFilter(); /// /// Saves if the filter should copy the data or just reference it /// mitk::WeakPointer m_Image; IplImage* m_OpenCVImage; }; -template -void mitk::ImageToOpenCVImageFilter::ItkImageProcessing( itk::Image* image ) -{ - m_OpenCVImage = itk::OpenCVImageBridge::ITKImageToIplImage (image); -} - } // namespace #endif // mitkImageToOpenCVImageFilter_h diff --git a/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.cpp b/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.cpp index ec4281bbca..f41f8b94c1 100644 --- a/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.cpp +++ b/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.cpp @@ -1,133 +1,168 @@ /*=================================================================== 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 "mitkOpenCVToMitkImageFilter.h" #include #include #include #include #include -mitk::OpenCVToMitkImageFilter::OpenCVToMitkImageFilter() -: m_OpenCVImage(0) -{ -} - -mitk::OpenCVToMitkImageFilter::~OpenCVToMitkImageFilter() -{ -} - -void mitk::OpenCVToMitkImageFilter::SetOpenCVImage(const IplImage* image) -{ - this->m_OpenCVImage = image; - this->Modified(); -} - -void mitk::OpenCVToMitkImageFilter::GenerateData() -{ - IplImage cvMatIplImage; - const IplImage* targetImage = 0; - if(m_OpenCVImage == 0) +#include "mitkImageToOpenCVImageFilter.h" + +namespace mitk{ + + OpenCVToMitkImageFilter::OpenCVToMitkImageFilter() + : m_OpenCVImage(0) + { + } + + OpenCVToMitkImageFilter::~OpenCVToMitkImageFilter() + { + } + + void OpenCVToMitkImageFilter::SetOpenCVImage(const IplImage* image) { + this->m_OpenCVImage = image; + this->m_OpenCVMat = NULL; + this->Modified(); + } + + void OpenCVToMitkImageFilter::GenerateData() + { + IplImage cvMatIplImage; + const IplImage* targetImage = 0; + if(m_OpenCVImage == 0) + { if( m_OpenCVMat.cols == 0 || m_OpenCVMat.rows == 0 ) { MITK_WARN << "Cannot not start filter. OpenCV Image not set."; return; } else { - cvMatIplImage = m_OpenCVMat; - targetImage = &cvMatIplImage; + cvMatIplImage = m_OpenCVMat; + targetImage = &cvMatIplImage; } - } - else + } + else targetImage = m_OpenCVImage; - // now convert rgb image - if( (targetImage->depth>=0) && ((unsigned int)targetImage->depth == IPL_DEPTH_8S) && (targetImage->nChannels == 1) ) - m_Image = ConvertIplToMitkImage< char, 2>( targetImage ); - - else if( targetImage->depth == IPL_DEPTH_8U && targetImage->nChannels == 1 ) - m_Image = ConvertIplToMitkImage< unsigned char, 2>( targetImage ); - - else if( targetImage->depth == IPL_DEPTH_8U && targetImage->nChannels == 3 ) - m_Image = ConvertIplToMitkImage< UCRGBPixelType, 2>( targetImage ); - - else if( targetImage->depth == IPL_DEPTH_16U && targetImage->nChannels == 1 ) - m_Image = ConvertIplToMitkImage< unsigned short, 2>( targetImage ); + // now convert rgb image + if( (targetImage->depth>=0) && ((unsigned int)targetImage->depth == IPL_DEPTH_8S) && (targetImage->nChannels == 1) ) + m_Image = ConvertIplToMitkImage< char, 2>( targetImage ); - else if( targetImage->depth == IPL_DEPTH_16U && targetImage->nChannels == 3 ) - m_Image = ConvertIplToMitkImage< USRGBPixelType, 2>( targetImage ); + else if( targetImage->depth == IPL_DEPTH_8U && targetImage->nChannels == 1 ) + m_Image = ConvertIplToMitkImage< unsigned char, 2>( targetImage ); - else if( targetImage->depth == IPL_DEPTH_32F && targetImage->nChannels == 1 ) - m_Image = ConvertIplToMitkImage< float, 2>( targetImage ); + else if( targetImage->depth == IPL_DEPTH_8U && targetImage->nChannels == 3 ) + m_Image = ConvertIplToMitkImage< UCRGBPixelType, 2>( targetImage ); - else if( targetImage->depth == IPL_DEPTH_32F && targetImage->nChannels == 3 ) - m_Image = ConvertIplToMitkImage< FloatRGBPixelType , 2>( targetImage ); + else if( targetImage->depth == IPL_DEPTH_16U && targetImage->nChannels == 1 ) + m_Image = ConvertIplToMitkImage< unsigned short, 2>( targetImage ); - else if( targetImage->depth == IPL_DEPTH_64F && targetImage->nChannels == 1 ) - m_Image = ConvertIplToMitkImage< double, 2>( targetImage ); + else if( targetImage->depth == IPL_DEPTH_16U && targetImage->nChannels == 3 ) + m_Image = ConvertIplToMitkImage< USRGBPixelType, 2>( targetImage ); - else if( targetImage->depth == IPL_DEPTH_64F && targetImage->nChannels == 3 ) - m_Image = ConvertIplToMitkImage< DoubleRGBPixelType , 2>( targetImage ); + else if( targetImage->depth == IPL_DEPTH_32F && targetImage->nChannels == 1 ) + m_Image = ConvertIplToMitkImage< float, 2>( targetImage ); - else - { - MITK_WARN << "Unknown image depth and/or pixel type. Cannot convert OpenCV to MITK image."; - return; - } + else if( targetImage->depth == IPL_DEPTH_32F && targetImage->nChannels == 3 ) + m_Image = ConvertIplToMitkImage< FloatRGBPixelType , 2>( targetImage ); - //cvReleaseImage(&rgbOpenCVImage); -} + else if( targetImage->depth == IPL_DEPTH_64F && targetImage->nChannels == 1 ) + m_Image = ConvertIplToMitkImage< double, 2>( targetImage ); -mitk::ImageSource::OutputImageType* mitk::OpenCVToMitkImageFilter::GetOutput() -{ - return m_Image; -} + else if( targetImage->depth == IPL_DEPTH_64F && targetImage->nChannels == 3 ) + m_Image = ConvertIplToMitkImage< DoubleRGBPixelType , 2>( targetImage ); -/******************************************** -* Converting from OpenCV image to ITK Image -*********************************************/ -template -mitk::Image::Pointer mitk::OpenCVToMitkImageFilter::ConvertIplToMitkImage( const IplImage * input, bool ) -{ - mitk::Image::Pointer mitkImage(0); + else + { + MITK_WARN << "Unknown image depth and/or pixel type. Cannot convert OpenCV to MITK image."; + return; + } - typedef itk::Image< TPixel, VImageDimension > ImageType; - - typename ImageType::Pointer output = itk::OpenCVImageBridge::IplImageToITKImage(input); + //cvReleaseImage(&rgbOpenCVImage); + } - mitkImage = mitk::GrabItkImageMemory(output); + ImageSource::OutputImageType* OpenCVToMitkImageFilter::GetOutput() + { + return m_Image; + } - return mitkImage; -} + /******************************************** + * Converting from OpenCV image to ITK Image + *********************************************/ + template + Image::Pointer mitk::OpenCVToMitkImageFilter::ConvertIplToMitkImage( const IplImage * input, bool ) + { + typedef itk::Image< TPixel, VImageDimension > ImageType; + + typename ImageType::Pointer output = ImageType::New(); + typename ImageType::RegionType region; + typename ImageType::RegionType::SizeType size; + typename ImageType::RegionType::IndexType index; + typename ImageType::SpacingType spacing; + size.Fill( 1 ); + size[0] = input->width; + size[1] = input->height; + index.Fill(0); + spacing.Fill(1); + region.SetSize(size); + region.SetIndex(index); + output->SetRegions(region); + output->SetSpacing(spacing); + output->Allocate(); + + // CAVE: The itk openCV bridge seem to NOT correctly copy the image data, hence the call to + // itk::OpenCVImageBridge::IplImageToITKImage() is simply used to initialize the itk image + // and in the next step the image data are copied by hand! + + if(input->nChannels == 3) // these are RGB images and need to be set to BGR before conversion! + { + output = itk::OpenCVImageBridge::IplImageToITKImage(input); + } + else + { + memcpy((void*) output->GetBufferPointer(), (void*) input->imageDataOrigin, + input->width*input->height*sizeof(TPixel)); + } + + Image::Pointer mitkImage = Image::New(); + mitkImage = GrabItkImageMemory(output); + + return mitkImage; + } -void mitk::OpenCVToMitkImageFilter::SetOpenCVMat(const cv::Mat &image) -{ + void OpenCVToMitkImageFilter::SetOpenCVMat(const cv::Mat &image) + { m_OpenCVMat = image; -} + m_OpenCVImage = NULL; + } -void mitk::OpenCVToMitkImageFilter::SetCopyBuffer(bool) -{ -} + void OpenCVToMitkImageFilter::SetCopyBuffer(bool) + { + } -bool mitk::OpenCVToMitkImageFilter::GetCopyBuffer() -{ + bool OpenCVToMitkImageFilter::GetCopyBuffer() + { return true; -} + } + +} // end namespace mitk \ No newline at end of file diff --git a/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.h b/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.h index 9a339412c0..d7e567c4bc 100644 --- a/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.h +++ b/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.h @@ -1,84 +1,88 @@ /*=================================================================== 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 mitkOpenCVToMitkImageFilter_h #define mitkOpenCVToMitkImageFilter_h +// mitk includes +#include "mitkOpenCVVideoSupportExports.h" #include #include + +// itk includes #include #include -#include -#include "mitkOpenCVVideoSupportExports.h" +// OpenCV includes +#include namespace mitk { /// /// \brief Filter for creating MITK RGB Images from an OpenCV image /// class MITK_OPENCVVIDEOSUPPORT_EXPORT OpenCVToMitkImageFilter : public ImageSource { public: typedef itk::RGBPixel< unsigned char > UCRGBPixelType; typedef itk::RGBPixel< unsigned short > USRGBPixelType; typedef itk::RGBPixel< float > FloatRGBPixelType; typedef itk::RGBPixel< double > DoubleRGBPixelType; /// /// the static function for the conversion /// WARNING: copyBuffer is deprecated, data will always be copied /// template - static mitk::Image::Pointer ConvertIplToMitkImage( const IplImage * input, bool copyBuffer=true ); + static Image::Pointer ConvertIplToMitkImage( const IplImage * input, bool copyBuffer=true ); mitkClassMacro(OpenCVToMitkImageFilter, ImageSource); itkNewMacro(OpenCVToMitkImageFilter); /// /// sets an iplimage as input /// void SetOpenCVImage(const IplImage* image); itkGetMacro(OpenCVImage, const IplImage*); /// /// sets an opencv mat as input (will be used if OpenCVImage Ipl image is 0) /// void SetOpenCVMat(const cv::Mat& image); itkGetMacro(OpenCVMat, cv::Mat); DEPRECATED( void SetCopyBuffer( bool ); ); DEPRECATED( bool GetCopyBuffer(); ); OutputImageType* GetOutput(void); protected: OpenCVToMitkImageFilter(); // purposely hidden virtual ~OpenCVToMitkImageFilter(); virtual void GenerateData(); protected: - mitk::Image::Pointer m_Image; + Image::Pointer m_Image; const IplImage* m_OpenCVImage; cv::Mat m_OpenCVMat; }; -} // namespace +} // namespace mitk #endif // mitkOpenCVToMitkImageFilter_h