diff --git a/Modules/OpenCVVideoSupport/Testing/mitkImageToOpenCVImageFilterTest.cpp b/Modules/OpenCVVideoSupport/Testing/mitkImageToOpenCVImageFilterTest.cpp index 7b2bcebb21..0c70c0b92e 100644 --- a/Modules/OpenCVVideoSupport/Testing/mitkImageToOpenCVImageFilterTest.cpp +++ b/Modules/OpenCVVideoSupport/Testing/mitkImageToOpenCVImageFilterTest.cpp @@ -1,178 +1,145 @@ /*=================================================================== 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 "mitkOpenCVToMitkImageFilter.h" #include #include #include #include +#include +#include +#include -/* -static void testGeneratedImage() -{ - // create itk rgb image - typedef unsigned char PixelType; - typedef itk::Image< itk::RGBPixel, 2 > ImageType; - ImageType::Pointer itkImage = ImageType::New(); - - ImageType::IndexType start; - start[0] = 0; // first index on X - start[1] = 0; // first index on Y - ImageType::SizeType size; - size[0] = 50; // size along X - size[1] = 40; // size along Y - ImageType::RegionType region; - region.SetSize( size ); - region.SetIndex( start ); - itkImage->SetRegions( region ); - itkImage->Allocate(); - - typedef itk::ImageRegionIterator IteratorType; - IteratorType it(itkImage, region); - float twoThirdsTheWidth = size[0] / 4; - unsigned int x=0, y=0; - // create rgb pic - for ( it.GoToBegin(); !it.IsAtEnd(); ++it ) - { - ImageType::PixelType newPixel; - newPixel.SetRed(0); - newPixel.SetGreen(0); - // create asymmetric pic - if( x > twoThirdsTheWidth ) - newPixel.SetBlue(0); - else - newPixel.SetBlue(255); - it.Set(newPixel); - - ++x; - // next line found - if( x == size[0] ) - x = 0; - } - - // debugging - // itk::ImageFileWriter< ImageType >::Pointer writer = itk::ImageFileWriter< ImageType >::New(); - // writer->SetFileName( "c:\\image.png" ); - // writer->SetInput ( itkImage ); - // writer->Update(); - - // import rgb image as MITK image - mitk::Image::Pointer mitkImage = mitk::ImportItkImage(itkImage)->Clone(); - - mitk::ImageToOpenCVImageFilter::Pointer _ImageToOpenCVImageFilter = - mitk::ImageToOpenCVImageFilter::New(); - - _ImageToOpenCVImageFilter->SetImage( mitkImage ); - - IplImage* openCVImage = _ImageToOpenCVImageFilter->GetOpenCVImage(); - - MITK_TEST_CONDITION_REQUIRED( openCVImage != NULL, "Image returned by filter is not null."); - - // check byte size - const unsigned int expectedSize = size[0] * size[1] * 3 * sizeof( unsigned char);// sizeof( PixelType ); - const unsigned int realSize = openCVImage->width * openCVImage->height * openCVImage->nChannels * sizeof( unsigned char);//* sizeof ( PixelType ); - MITK_TEST_CONDITION_REQUIRED( expectedSize == realSize, "Test expectedSize == realSize"); - - // check pixel values - PixelType expectedBlueValue; - CvScalar s; - for (y = 0; (int)y < openCVImage->height; ++y) - { - for (x = 0; (int)x < openCVImage->width; ++x) - { - expectedBlueValue = 255; - if(x > twoThirdsTheWidth) - expectedBlueValue = 0; - - s = cvGet2D(openCVImage,y,x); - if( s.val[0] != expectedBlueValue || s.val[1] != 0 || s.val[2] != 0 ) - { - std::cout << "Wrong RGB values in created OpenCV image" << std::endl; - throw mitk::TestFailedException(); - } - } - } - -// cvNamedWindow( "test" ); -// cvShowImage( "test" , openCVImage ); -// cvWaitKey(); +// define test pixel indexes and intensities and other values +typedef itk::RGBPixel< unsigned char > TestUCRGBPixelType; -} +cv::Size testImageSize; -static void testLoadedImage(std::string mitkImagePath) -{ - mitk::Image::Pointer testImage = LoadImage(mitkImagePath); - mitk::ImageToOpenCVImageFilter::Pointer _ImageToOpenCVImageFilter = - mitk::ImageToOpenCVImageFilter::New(); - - _ImageToOpenCVImageFilter->SetImage( testImage ); - - IplImage* openCVImage = _ImageToOpenCVImageFilter->GetOpenCVImage(); - IplImage* openCVImage_Ref = cvLoadImage(mitkImagePath.c_str()); - - MITK_TEST_CONDITION_REQUIRED( openCVImage != NULL, "Image returned by filter is not null."); - - for(int i = 0 ; iheight ; i++) - { - for(int j = 0 ; jwidth ; j++) - { - CvScalar s; - s=cvGet2D(openCVImage,i,j); // get the (i,j) pixel value - CvScalar sRef; - sRef=cvGet2D(openCVImage_Ref,i,j); // get the (i,j) pixel value - for(int c = 0 ; c < openCVImage->nChannels ; c++) - { - MITK_TEST_CONDITION_REQUIRED( s.val[c] == sRef.val[c] , "All pixel values have to be equal"); - } - } - } - - -// cvNamedWindow( "test" ); -// cvShowImage( "test" , openCVImage ); -// cvWaitKey(); -} +cv::Point pos1; +cv::Point pos2; +cv::Point pos3; -void testGeneratedImage() -/**Documentation - * test for the class "ImageToOpenCVImageFilter". - */ +cv::Vec3b color1; +cv::Vec3b color2; +cv::Vec3b color3; -cv::Mat generateImage() +uchar greyValue1; +uchar greyValue2; +uchar greyValue3; + +template +void ComparePixels( itk::Image,VImageDimension>* image ) { - cv::Mat testImage = cv::Mat::zeros( 240, 320, CV_8UC3 ); - testImage.at(0, 0) = 10; - testImage.at(160, 120) = 128; - testImage.at(319, 239) = 255; - return testImage; + + + 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"); + } int mitkImageToOpenCVImageFilterTest(int argc, char* argv[]) { MITK_TEST_BEGIN("ImageToOpenCVImageFilter") - cv::Mat testImage = generateImage(); - cv::imshow("testImage", testImage); - cv::waitKey(10000); - //testGeneratedImage(); - //testLoadedImage(argv[1]); - // always end with this! + 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); + + 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) ); + + + 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(); + + 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" ) + MITK_TEST_END(); } diff --git a/Modules/OpenCVVideoSupport/mitkImageToOpenCVImageFilter.cpp b/Modules/OpenCVVideoSupport/mitkImageToOpenCVImageFilter.cpp index c6fe758fc7..e26bfa3cfc 100644 --- a/Modules/OpenCVVideoSupport/mitkImageToOpenCVImageFilter.cpp +++ b/Modules/OpenCVVideoSupport/mitkImageToOpenCVImageFilter.cpp @@ -1,85 +1,92 @@ /*=================================================================== 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) { MITK_WARN << "MITK Image is 0"; return false; } if(image->GetDimension() != 2) { MITK_WARN << "Only 2D Images allowed"; return false; } return true; } IplImage* mitk::ImageToOpenCVImageFilter::GetOpenCVImage() { m_OpenCVImage = 0; if(!this->CheckImage( m_Image )) return 0; try { AccessFixedTypeByItk(m_Image.GetPointer(), ItkImageProcessing, 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; } cv::Mat mitk::ImageToOpenCVImageFilter::GetOpenCVMat() { IplImage* img = this->GetOpenCVImage(); + //cvNamedWindow("debug2", CV_WINDOW_FREERATIO); + //cvShowImage("debug2", img); + //cv::waitKey(0); cv::Mat mat; if( img ) - mat = cv::Mat ( img, true ); + { + // do not copy data, then release just the header + mat = cv::Mat ( img, false ); + cvReleaseImageHeader( &img ); + } return mat; } void mitk::ImageToOpenCVImageFilter::SetImage( mitk::Image* _Image ) { // if(m_Image == _Image) return; m_Image = _Image; } diff --git a/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.cpp b/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.cpp index f8aab4d9f9..ec4281bbca 100644 --- a/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.cpp +++ b/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.cpp @@ -1,116 +1,133 @@ /*=================================================================== 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), m_CopyBuffer(true) +: 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) { 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; } } 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, m_CopyBuffer ); + m_Image = ConvertIplToMitkImage< char, 2>( targetImage ); else if( targetImage->depth == IPL_DEPTH_8U && targetImage->nChannels == 1 ) - m_Image = ConvertIplToMitkImage< unsigned char, 2>( targetImage, m_CopyBuffer ); + m_Image = ConvertIplToMitkImage< unsigned char, 2>( targetImage ); else if( targetImage->depth == IPL_DEPTH_8U && targetImage->nChannels == 3 ) - m_Image = ConvertIplToMitkImage< UCRGBPixelType, 2>( targetImage, m_CopyBuffer ); + m_Image = ConvertIplToMitkImage< UCRGBPixelType, 2>( targetImage ); else if( targetImage->depth == IPL_DEPTH_16U && targetImage->nChannels == 1 ) - m_Image = ConvertIplToMitkImage< unsigned short, 2>( targetImage, m_CopyBuffer ); + m_Image = ConvertIplToMitkImage< unsigned short, 2>( targetImage ); else if( targetImage->depth == IPL_DEPTH_16U && targetImage->nChannels == 3 ) - m_Image = ConvertIplToMitkImage< USRGBPixelType, 2>( targetImage, m_CopyBuffer ); + m_Image = ConvertIplToMitkImage< USRGBPixelType, 2>( targetImage ); else if( targetImage->depth == IPL_DEPTH_32F && targetImage->nChannels == 1 ) - m_Image = ConvertIplToMitkImage< float, 2>( targetImage, m_CopyBuffer ); + m_Image = ConvertIplToMitkImage< float, 2>( targetImage ); else if( targetImage->depth == IPL_DEPTH_32F && targetImage->nChannels == 3 ) - m_Image = ConvertIplToMitkImage< FloatRGBPixelType , 2>( targetImage, m_CopyBuffer ); + m_Image = ConvertIplToMitkImage< FloatRGBPixelType , 2>( targetImage ); else if( targetImage->depth == IPL_DEPTH_64F && targetImage->nChannels == 1 ) - m_Image = ConvertIplToMitkImage< double, 2>( targetImage, m_CopyBuffer ); + m_Image = ConvertIplToMitkImage< double, 2>( targetImage ); else if( targetImage->depth == IPL_DEPTH_64F && targetImage->nChannels == 3 ) - m_Image = ConvertIplToMitkImage< DoubleRGBPixelType , 2>( targetImage, m_CopyBuffer ); + m_Image = ConvertIplToMitkImage< DoubleRGBPixelType , 2>( targetImage ); else { MITK_WARN << "Unknown image depth and/or pixel type. Cannot convert OpenCV to MITK image."; return; } //cvReleaseImage(&rgbOpenCVImage); } mitk::ImageSource::OutputImageType* mitk::OpenCVToMitkImageFilter::GetOutput() { return m_Image; } /******************************************** * Converting from OpenCV image to ITK Image *********************************************/ template -mitk::Image::Pointer mitk::OpenCVToMitkImageFilter::ConvertIplToMitkImage( const IplImage * input, bool copyBuffer ) +mitk::Image::Pointer mitk::OpenCVToMitkImageFilter::ConvertIplToMitkImage( const IplImage * input, bool ) { mitk::Image::Pointer mitkImage(0); - typedef itk::Image< TPixel, VImageDimension > ItkImage; + typedef itk::Image< TPixel, VImageDimension > ImageType; - typename ItkImage::Pointer output = itk::OpenCVImageBridge::IplImageToITKImage(input); + typename ImageType::Pointer output = itk::OpenCVImageBridge::IplImageToITKImage(input); - mitkImage = mitk::ImportItkImage(output); + mitkImage = mitk::GrabItkImageMemory(output); return mitkImage; } + + +void mitk::OpenCVToMitkImageFilter::SetOpenCVMat(const cv::Mat &image) +{ + m_OpenCVMat = image; +} + + +void mitk::OpenCVToMitkImageFilter::SetCopyBuffer(bool) +{ +} + +bool mitk::OpenCVToMitkImageFilter::GetCopyBuffer() +{ + return true; +} diff --git a/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.h b/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.h index 6b15548e21..9a339412c0 100644 --- a/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.h +++ b/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.h @@ -1,84 +1,84 @@ /*=================================================================== 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 #include #include #include #include #include #include "mitkOpenCVVideoSupportExports.h" 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 mitk::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 SetGetOpenCVMat(const cv::Mat& image); + void SetOpenCVMat(const cv::Mat& image); itkGetMacro(OpenCVMat, cv::Mat); - itkSetMacro(CopyBuffer, bool); - itkGetMacro(CopyBuffer, bool); + 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; const IplImage* m_OpenCVImage; cv::Mat m_OpenCVMat; - bool m_CopyBuffer; }; } // namespace #endif // mitkOpenCVToMitkImageFilter_h