diff --git a/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.cpp b/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.cpp index 4f4f09ea53..d4241fb627 100644 --- a/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.cpp +++ b/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.cpp @@ -1,166 +1,178 @@ /*=================================================================== 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 mitk::OpenCVToMitkImageFilter::OpenCVToMitkImageFilter() : m_OpenCVImage(0), m_CopyBuffer(true) { } mitk::OpenCVToMitkImageFilter::~OpenCVToMitkImageFilter() { } +void mitk::OpenCVToMitkImageFilter::SetOpenCVImage(const IplImage* image) +{ + this->m_OpenCVImage = image; + this->Modified(); +} + void mitk::OpenCVToMitkImageFilter::GenerateData() { if(m_OpenCVImage == 0) { MITK_WARN << "Cannot not start filter. OpenCV Image not set."; return; } // convert to rgb image color space IplImage* rgbOpenCVImage = cvCreateImage( cvSize( m_OpenCVImage->width, m_OpenCVImage->height ) , m_OpenCVImage->depth, m_OpenCVImage->nChannels ); if( m_OpenCVImage->nChannels == 3) cvCvtColor( m_OpenCVImage, rgbOpenCVImage, CV_BGR2RGB ); // now convert rgb image if( (m_OpenCVImage->depth>=0) && ((unsigned int)m_OpenCVImage->depth == IPL_DEPTH_8S) && (m_OpenCVImage->nChannels == 1) ) m_Image = ConvertIplToMitkImage< char, 2>( m_OpenCVImage, m_CopyBuffer ); else if( m_OpenCVImage->depth == IPL_DEPTH_8U && m_OpenCVImage->nChannels == 1 ) m_Image = ConvertIplToMitkImage< unsigned char, 2>( m_OpenCVImage, m_CopyBuffer ); else if( m_OpenCVImage->depth == IPL_DEPTH_8U && m_OpenCVImage->nChannels == 3 ) m_Image = ConvertIplToMitkImage< UCRGBPixelType, 2>( rgbOpenCVImage, m_CopyBuffer ); else if( m_OpenCVImage->depth == IPL_DEPTH_16U && m_OpenCVImage->nChannels == 1 ) m_Image = ConvertIplToMitkImage< unsigned short, 2>( m_OpenCVImage, m_CopyBuffer ); else if( m_OpenCVImage->depth == IPL_DEPTH_16U && m_OpenCVImage->nChannels == 3 ) m_Image = ConvertIplToMitkImage< USRGBPixelType, 2>( rgbOpenCVImage, m_CopyBuffer ); else if( m_OpenCVImage->depth == IPL_DEPTH_32F && m_OpenCVImage->nChannels == 1 ) m_Image = ConvertIplToMitkImage< float, 2>( m_OpenCVImage, m_CopyBuffer ); else if( m_OpenCVImage->depth == IPL_DEPTH_32F && m_OpenCVImage->nChannels == 3 ) m_Image = ConvertIplToMitkImage< FloatRGBPixelType , 2>( rgbOpenCVImage, m_CopyBuffer ); else if( m_OpenCVImage->depth == IPL_DEPTH_64F && m_OpenCVImage->nChannels == 1 ) m_Image = ConvertIplToMitkImage< double, 2>( m_OpenCVImage, m_CopyBuffer ); else if( m_OpenCVImage->depth == IPL_DEPTH_64F && m_OpenCVImage->nChannels == 3 ) m_Image = ConvertIplToMitkImage< DoubleRGBPixelType , 2>( rgbOpenCVImage, m_CopyBuffer ); + else + { + MITK_WARN << "Unknown image depth and/or pixel type. Cannot convert OpenCV to MITK image."; + return; + } + cvReleaseImage(&rgbOpenCVImage); } mitk::ImageSource::DataObjectPointer mitk::OpenCVToMitkImageFilter::MakeOutput( unsigned int idx ) { return Superclass::MakeOutput(idx); } mitk::ImageSource::OutputImageType* mitk::OpenCVToMitkImageFilter::GetOutput( unsigned int /*idx*/ ) { 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 mitkImage(0); typedef itk::Image< TPixel, VImageDimension > ItkImage; typedef itk::ImportImageFilter< TPixel, VImageDimension > ImportFilterType; typename ImportFilterType::Pointer importFilter = ImportFilterType::New(); typename ImportFilterType::SizeType size; size[0] = input->width; size[1] = input->height; typename ImportFilterType::IndexType start; start.Fill( 0 ); typename ImportFilterType::RegionType region; region.SetIndex( start ); region.SetSize( size ); importFilter->SetRegion( region ); double origin[ VImageDimension ]; origin[0] = 0.0; // X coordinate origin[1] = 0.0; // Y coordinate importFilter->SetOrigin( origin ); double spacing[ VImageDimension ]; spacing[0] = 1.0; // along X direction spacing[1] = 1.0; // along Y direction importFilter->SetSpacing( spacing ); const unsigned int numberOfPixels = size[0] * size[1]; const unsigned int numberOfBytes = numberOfPixels * sizeof( TPixel ); if( copyBuffer ) { const bool importImageFilterWillOwnTheBuffer = false; TPixel * localBuffer = new TPixel[numberOfPixels]; memcpy(localBuffer, input->imageData, numberOfBytes); importFilter->SetImportPointer( localBuffer, numberOfPixels, importImageFilterWillOwnTheBuffer ); } else { const bool importImageFilterWillOwnTheBuffer = false; TPixel * localBuffer = reinterpret_cast< TPixel * >( input->imageData ); importFilter->SetImportPointer( localBuffer, numberOfPixels, importImageFilterWillOwnTheBuffer ); } importFilter->Update(); typename ItkImage::Pointer output = importFilter->GetOutput(); output->DisconnectPipeline(); mitkImage = mitk::ImportItkImage( output ); return mitkImage; } diff --git a/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.h b/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.h index f93bdd85c8..fd51b57eff 100644 --- a/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.h +++ b/Modules/OpenCVVideoSupport/mitkOpenCVToMitkImageFilter.h @@ -1,77 +1,77 @@ /*=================================================================== 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 #include "mitkOpenCVVideoSupportExports.h" namespace mitk { /** \brief Filter for creating MITK RGB Images from an OpenCV image Last contributor: $Author: mueller $ */ 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; template static mitk::Image::Pointer ConvertIplToMitkImage( const IplImage * input, bool copyBuffer = true ); mitkClassMacro(OpenCVToMitkImageFilter, ImageSource); itkNewMacro(OpenCVToMitkImageFilter); - itkSetObjectMacro(OpenCVImage, const IplImage); + void SetOpenCVImage(const IplImage* image); itkGetMacro(OpenCVImage, const IplImage*); itkSetMacro(CopyBuffer, bool); itkGetMacro(CopyBuffer, bool); virtual DataObjectPointer MakeOutput(unsigned int idx); OutputImageType* GetOutput(unsigned int idx); protected: OpenCVToMitkImageFilter(); // purposely hidden virtual ~OpenCVToMitkImageFilter(); virtual void GenerateData(); protected: mitk::Image::Pointer m_Image; const IplImage* m_OpenCVImage; bool m_CopyBuffer; }; } // namespace #endif // mitkOpenCVToMitkImageFilter_h diff --git a/Modules/US/USFilters/mitkUSImageVideoSource.cpp b/Modules/US/USFilters/mitkUSImageVideoSource.cpp index 4ae1a6d51f..e80dc4005c 100644 --- a/Modules/US/USFilters/mitkUSImageVideoSource.cpp +++ b/Modules/US/USFilters/mitkUSImageVideoSource.cpp @@ -1,112 +1,128 @@ /*=================================================================== 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 HEADER #include "mitkUSImageVideoSource.h" #include "mitkImage.h" //OpenCV HEADER #include #include //Other #include mitk::USImageVideoSource::USImageVideoSource() : itk::Object() { m_IsVideoReady = false; - m_IsMetadataReady = false; - m_IsGeometryReady = false; + m_IsGreyscale = true; this->m_OpenCVToMitkFilter = mitk::OpenCVToMitkImageFilter::New(); } mitk::USImageVideoSource::~USImageVideoSource() { } void mitk::USImageVideoSource::SetVideoFileInput(std::string path) { m_OpenCVVideoSource = mitk::OpenCVVideoSource::New(); - // Example: "C:\\Users\\maerz\\Videos\\Debut\\us.avi" m_OpenCVVideoSource->SetVideoFileInput(path.c_str(),true,false); m_OpenCVVideoSource->StartCapturing(); m_OpenCVVideoSource->FetchFrame(); // Let's see if we have been successful m_IsVideoReady = m_OpenCVVideoSource->IsCapturingEnabled(); } void mitk::USImageVideoSource::SetCameraInput(int deviceID) { - - - - // Old Code, this may not work m_OpenCVVideoSource = mitk::OpenCVVideoSource::New(); - m_OpenCVVideoSource->SetVideoCameraInput(deviceID); m_OpenCVVideoSource->StartCapturing(); m_OpenCVVideoSource->FetchFrame(); // Let's see if we have been successful m_IsVideoReady = m_OpenCVVideoSource->IsCapturingEnabled(); } +void mitk::USImageVideoSource::SetColorOutput(bool isColor){ + m_IsGreyscale = !isColor; +} + +void mitk::USImageVideoSource::SetRegionOfInterest(int topLeftX, int topLeftY, int bottomRightX, int bottomRightY) +{ + // First, let's do some basic checks to make sure rectangle is inside of actual image + if (topLeftX < 0) topLeftX = 0; + if (topLeftY < 0) topLeftY = 0; + + if (bottomRightX > m_OpenCVVideoSource->GetImageWidth()) bottomRightX = m_OpenCVVideoSource->GetImageWidth(); + if (bottomRightX > m_OpenCVVideoSource->GetImageHeight()) bottomRightY = m_OpenCVVideoSource->GetImageHeight(); + + if (topLeftX > bottomRightX) mitkThrow() << "Invalid boundaries supplied to USImageVideoSource::SetRegionOfInterest()"; + if (topLeftY > bottomRightY) mitkThrow() << "Invalid boundaries supplied to USImageVideoSource::SetRegionOfInterest()"; + + m_CropRegion = cv::Rect(topLeftX, topLeftY, bottomRightX - topLeftX, bottomRightY - topLeftY); +} + +void mitk::USImageVideoSource::RemoveRegionOfInterest(){ + m_CropRegion.width = 0; + m_CropRegion.height = 0; +} mitk::USImage::Pointer mitk::USImageVideoSource::GetNextImage() { + // Setup Pointers + cv::Mat image; + cv::Mat buffer; -// The following code utilizes open CV directly do access images - //IplImage *m_cvCurrentVideoFrame = NULL; - //CvCapture* capture = cvCaptureFromCAM( 1000 ); - // if ( !capture ) { - // fprintf( stderr, "ERROR: capture is NULL \n" ); - // getchar(); - // return NULL; - // } - // // Show the image captured from the camera in the window and repeat - // - // // Get one frame - // m_cvCurrentVideoFrame = cvQueryFrame( capture ); - // -/// WORKING CODE - - - IplImage *m_cvCurrentVideoFrame = NULL; + //Get dimensions and init rgb + int width = m_OpenCVVideoSource->GetImageWidth(); int height = m_OpenCVVideoSource->GetImageHeight(); - int width = m_OpenCVVideoSource->GetImageWidth(); - m_cvCurrentVideoFrame = cvCreateImage(cvSize(width,height),8,3); - m_OpenCVVideoSource->GetCurrentFrameAsOpenCVImage(m_cvCurrentVideoFrame); + + // Get Frame from Source + image = m_OpenCVVideoSource->GetImage(); m_OpenCVVideoSource->FetchFrame(); - this->m_OpenCVToMitkFilter->SetOpenCVImage(m_cvCurrentVideoFrame); + + // if Region of interest is set, crop image + if (m_CropRegion.width > 0){ + buffer = image(m_CropRegion); + image = buffer; + } + // If this is a greyscale image, convert it + if (m_IsGreyscale) + { + cv::cvtColor(image, buffer, CV_RGB2GRAY, 1); + image = buffer; + } + IplImage ipl_img = image; + this->m_OpenCVToMitkFilter->SetOpenCVImage(&ipl_img); + this->m_OpenCVToMitkFilter->Update(); - // OpenCVToMitkImageFilter returns a standard mit::image. We then transform it into an USImage + // OpenCVToMitkImageFilter returns a standard mitk::image. We then transform it into an USImage mitk::USImage::Pointer result = mitk::USImage::New(this->m_OpenCVToMitkFilter->GetOutput(0)); - - cvReleaseImage (&m_cvCurrentVideoFrame); return result; } diff --git a/Modules/US/USFilters/mitkUSImageVideoSource.h b/Modules/US/USFilters/mitkUSImageVideoSource.h index 954114ca95..f527be52ff 100644 --- a/Modules/US/USFilters/mitkUSImageVideoSource.h +++ b/Modules/US/USFilters/mitkUSImageVideoSource.h @@ -1,87 +1,99 @@ /*=================================================================== 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 MITKUSImageVideoSource_H_HEADER_INCLUDED_ #define MITKUSImageVideoSource_H_HEADER_INCLUDED_ #include #include "mitkUSImage.h" #include "mitkOpenCVVideoSource.h" #include "mitkOpenCVToMitkImageFilter.h" namespace mitk { /**Documentation * \brief This class can be pointed to a video file or a videodevice and delivers USImages with default metadata Sets * * \ingroup US */ class MitkUS_EXPORT USImageVideoSource : public itk::Object { public: mitkClassMacro(USImageVideoSource, itk::ProcessObject); itkNewMacro(Self); /** *\brief Opens a video file for streaming. If nothing goes wrong, the * VideoSource is ready to deliver images after calling this function. */ void SetVideoFileInput(std::string path); /** *\brief Opens a video device for streaming. Takes the Device id. Try -1 for "grab the first you can get" * which works quite well if only one device is available. If nothing goes wrong, the * VideoSource is ready to deliver images after calling this function. */ void SetCameraInput(int deviceID); + /** + *\brief Sets the output image to rgb or grayscale. Output is grayscale by default + * and can be set to color by passing true, or to grayscale again by passing false. + */ + void SetColorOutput(bool isColor); + + /** + * /brief Defines the cropping area. The rectangle will be justified to the image borders + * if the given rectangle is larger than the video source. If a correct rectangle is given, + * The dimensions of the output image will be equal to those of the rectangle. + */ + void SetRegionOfInterest(int topLeftX, int topLeftY, int bottomRightX, int bottomRightY); + + /** + * /brief Removes the region of interest. Produced images will be uncropped after call. + */ + void RemoveRegionOfInterest(); + /** *\brief Retrieves the next frame. This will typically be the next frame in a file * or the last cahced file in a devcie. */ mitk::USImage::Pointer GetNextImage(); // Getter & Setter itkGetMacro(OpenCVVideoSource, mitk::OpenCVVideoSource::Pointer); itkSetMacro(OpenCVVideoSource, mitk::OpenCVVideoSource::Pointer); itkGetMacro(IsVideoReady, bool); - itkGetMacro(IsMetadataReady, bool); - itkGetMacro(IsGeometryReady, bool); protected: USImageVideoSource(); virtual ~USImageVideoSource(); - /** * \brief The source of the video */ mitk::OpenCVVideoSource::Pointer m_OpenCVVideoSource; - /** - * \brief The Following flags are used internally, to assure that all necessary steps are taken before capturing - */ bool m_IsVideoReady; - bool m_IsMetadataReady; - bool m_IsGeometryReady; + bool m_IsGreyscale; + cv::Rect m_CropRegion; mitk::OpenCVToMitkImageFilter::Pointer m_OpenCVToMitkFilter; }; } // namespace mitk #endif /* MITKUSImageVideoSource_H_HEADER_INCLUDED_ */