diff --git a/Modules/OpenCVVideoSupport/Commands/mitkAbstractOpenCVImageFilter.h b/Modules/OpenCVVideoSupport/Commands/mitkAbstractOpenCVImageFilter.h index 38482d9efc..b709869360 100644 --- a/Modules/OpenCVVideoSupport/Commands/mitkAbstractOpenCVImageFilter.h +++ b/Modules/OpenCVVideoSupport/Commands/mitkAbstractOpenCVImageFilter.h @@ -1,56 +1,57 @@ /*=================================================================== 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 mitkCropOpenCVImageFilter_h #define mitkCropOpenCVImageFilter_h #include "mitkOpenCVVideoSupportExports.h" #include //itk headers #include namespace cv { class Mat; } namespace mitk { /** * \brief Interface for image filters on OpenCV images. + * * Every concrete filter has to implement the pure virual * mitk::AbstractOpenCVImageFilter::filterImage() method. * */ class MITK_OPENCVVIDEOSUPPORT_EXPORT AbstractOpenCVImageFilter : public itk::Object { public: mitkClassMacro(AbstractOpenCVImageFilter, itk::Object); /** * \brief Pure virtual method for filtering an image. * * \param image OpenCV image which is supposed to be manipulated. * \return true if filtering was successfull, false otherwise */ - virtual bool filterImage( cv::Mat image ) = 0; + virtual bool FilterImage( cv::Mat& image ) = 0; }; } // namespace mitk #endif // mitkCropOpenCVImageFilter_h diff --git a/Modules/OpenCVVideoSupport/Commands/mitkConvertGrayscaleOpenCVImageFilter.cpp b/Modules/OpenCVVideoSupport/Commands/mitkConvertGrayscaleOpenCVImageFilter.cpp index fc5668c5e0..fc70d7685c 100644 --- a/Modules/OpenCVVideoSupport/Commands/mitkConvertGrayscaleOpenCVImageFilter.cpp +++ b/Modules/OpenCVVideoSupport/Commands/mitkConvertGrayscaleOpenCVImageFilter.cpp @@ -1,34 +1,34 @@ /*=================================================================== 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 "mitkConvertGrayscaleOpenCVImageFilter.h" #include "cv.h" namespace mitk { -bool ConvertGrayscaleOpenCVImageFilter::filterImage( cv::Mat image ) +bool ConvertGrayscaleOpenCVImageFilter::FilterImage( cv::Mat& image ) { cv::Mat buffer; cv::cvtColor(image, buffer, CV_RGB2GRAY, 1); image.release(); image = buffer; return true; } } // namespace mitk diff --git a/Modules/OpenCVVideoSupport/Commands/mitkConvertGrayscaleOpenCVImageFilter.h b/Modules/OpenCVVideoSupport/Commands/mitkConvertGrayscaleOpenCVImageFilter.h index 7eca0ba344..1311afc2bd 100644 --- a/Modules/OpenCVVideoSupport/Commands/mitkConvertGrayscaleOpenCVImageFilter.h +++ b/Modules/OpenCVVideoSupport/Commands/mitkConvertGrayscaleOpenCVImageFilter.h @@ -1,43 +1,43 @@ /*=================================================================== 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 mitkConvertGrayscaleOpenCVImageFilter_h #define mitkConvertGrayscaleOpenCVImageFilter_h #include "mitkAbstractOpenCVImageFilter.h" //itk headers #include "itkObjectFactory.h" namespace mitk { class MITK_OPENCVVIDEOSUPPORT_EXPORT ConvertGrayscaleOpenCVImageFilter : public AbstractOpenCVImageFilter { public: mitkClassMacro(ConvertGrayscaleOpenCVImageFilter, AbstractOpenCVImageFilter); itkNewMacro(Self); /** * \brief Converts given image to grayscale. * \return always true */ - bool filterImage( cv::Mat image ); + bool FilterImage( cv::Mat& image ); }; } // namespace mitk #endif // mitkConvertGrayscaleOpenCVImageFilter_h diff --git a/Modules/OpenCVVideoSupport/Commands/mitkCropOpenCVImageFilter.cpp b/Modules/OpenCVVideoSupport/Commands/mitkCropOpenCVImageFilter.cpp index aea1a53e59..85c2145e17 100644 --- a/Modules/OpenCVVideoSupport/Commands/mitkCropOpenCVImageFilter.cpp +++ b/Modules/OpenCVVideoSupport/Commands/mitkCropOpenCVImageFilter.cpp @@ -1,49 +1,76 @@ /*=================================================================== 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 "mitkCropOpenCVImageFilter.h" #include "cv.h" namespace mitk { -bool CropOpenCVImageFilter::filterImage( cv::Mat image ) +bool CropOpenCVImageFilter::FilterImage( cv::Mat& image ) { - if (m_CropRegion.width <= 0) + if (m_CropRegion.width == 0) { MITK_ERROR("AbstractOpenCVImageFilter")("CropOpenCVImageFilter") << "Cropping cannot be done without setting a non-empty crop region first."; return false; } - cv::Mat buffer = image(m_CropRegion); + cv::Rect cropRegion = m_CropRegion; + + // We can try and correct too large boundaries + if ( cropRegion.x + cropRegion.width >= image.size().width) + { + cropRegion.width = image.size().width - cropRegion.x; + } + if ( cropRegion.y + cropRegion.height >= image.size().height) + { + cropRegion.height = image.size().height - cropRegion.y; + } + + cv::Mat buffer = image(cropRegion); image.release(); image = buffer; return true; } void CropOpenCVImageFilter::SetCropRegion( cv::Rect cropRegion ) { + // First, let's do some basic checks to make sure rectangle is inside of actual image + if (cropRegion.x < 0) { cropRegion.x = 0; } + if (cropRegion.y < 0) { cropRegion.y = 0; } + + // Nothing to save, throw an exception + if ( cropRegion.height < 0 || cropRegion.width < 0 ) + { + mitkThrow() << "Invalid boundaries supplied to USImageVideoSource::SetRegionOfInterest()"; + } + m_CropRegion = cropRegion; } +void CropOpenCVImageFilter::SetCropRegion( int topLeftX, int topLeftY, int bottomRightX, int bottomRightY ) +{ + this->SetCropRegion( cv::Rect(topLeftX, topLeftY, bottomRightX - topLeftX, bottomRightY - topLeftY) ); +} + cv::Rect CropOpenCVImageFilter::GetCropRegion( ) { return m_CropRegion; } } // namespace mitk diff --git a/Modules/OpenCVVideoSupport/Commands/mitkCropOpenCVImageFilter.h b/Modules/OpenCVVideoSupport/Commands/mitkCropOpenCVImageFilter.h index 0bb3d9de45..f3eb88ccc5 100644 --- a/Modules/OpenCVVideoSupport/Commands/mitkCropOpenCVImageFilter.h +++ b/Modules/OpenCVVideoSupport/Commands/mitkCropOpenCVImageFilter.h @@ -1,54 +1,55 @@ /*=================================================================== 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 mitkAbstractOpenCVImageFilter_h #define mitkAbstractOpenCVImageFilter_h #include "mitkAbstractOpenCVImageFilter.h" #include "cv.h" //itk headers #include namespace mitk { class MITK_OPENCVVIDEOSUPPORT_EXPORT CropOpenCVImageFilter : public AbstractOpenCVImageFilter { public: mitkClassMacro(CropOpenCVImageFilter, AbstractOpenCVImageFilter); itkNewMacro(Self); /** * \brief Crops image to rectangle given by mitk::CropOpenCVImageFilter::SetCropRegion. * \return false if no crop region was set or the crop region width is zero, true otherwise. */ - bool filterImage( cv::Mat image ); + bool FilterImage( cv::Mat& image ); void SetCropRegion( cv::Rect cropRegion ); + void SetCropRegion( int topLeftX, int topLeftY, int bottomRightX, int bottomRightY ); cv::Rect GetCropRegion( ); protected: /** - * \brief Defines the region which will be cropped from the image. - */ + * \brief Defines the region which will be cropped from the image. + */ cv::Rect m_CropRegion; }; } // namespace mitk #endif // mitkAbstractOpenCVImageFilter_h diff --git a/Modules/US/USFilters/mitkUSImageVideoSource.cpp b/Modules/US/USFilters/mitkUSImageVideoSource.cpp index 3f55395cce..7de48125a5 100644 --- a/Modules/US/USFilters/mitkUSImageVideoSource.cpp +++ b/Modules/US/USFilters/mitkUSImageVideoSource.cpp @@ -1,169 +1,156 @@ /*=================================================================== 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" #include "Commands/mitkCropOpenCVImageFilter.h" #include "Commands/mitkConvertGrayscaleOpenCVImageFilter.h" //OpenCV HEADER #include #include //Other #include mitk::USImageVideoSource::USImageVideoSource() : itk::Object(), m_VideoCapture(new cv::VideoCapture()), m_IsVideoReady(false), m_IsGreyscale(false), m_OpenCVToMitkFilter(mitk::OpenCVToMitkImageFilter::New()), m_ResolutionOverrideWidth(0), m_ResolutionOverrideHeight(0), m_ResolutionOverride(false), m_ImageFilter(0), m_GrayscaleFilter(mitk::ConvertGrayscaleOpenCVImageFilter::New()), m_CropFilter(mitk::CropOpenCVImageFilter::New()) { m_OpenCVToMitkFilter->SetCopyBuffer(false); } mitk::USImageVideoSource::~USImageVideoSource() { } void mitk::USImageVideoSource::SetVideoFileInput(std::string path) { m_VideoCapture->open(path.c_str()); if(!m_VideoCapture->isOpened()) // check if we succeeded m_IsVideoReady = false; else m_IsVideoReady = true; // If Override is enabled, use it if (m_ResolutionOverride) { m_VideoCapture->set(CV_CAP_PROP_FRAME_WIDTH, this->m_ResolutionOverrideWidth); m_VideoCapture->set(CV_CAP_PROP_FRAME_HEIGHT, this->m_ResolutionOverrideHeight); } } void mitk::USImageVideoSource::SetCameraInput(int deviceID) { m_VideoCapture->open(deviceID); if(!m_VideoCapture->isOpened()) // check if we succeeded m_IsVideoReady = false; else m_IsVideoReady = true; // If Override is enabled, use it if (m_ResolutionOverride) { m_VideoCapture->set(CV_CAP_PROP_FRAME_WIDTH, this->m_ResolutionOverrideWidth); m_VideoCapture->set(CV_CAP_PROP_FRAME_HEIGHT, this->m_ResolutionOverrideHeight); } } void mitk::USImageVideoSource::SetColorOutput(bool isColor){ m_IsGreyscale = !isColor; } int mitk::USImageVideoSource::GetImageHeight() { if (m_VideoCapture) return m_VideoCapture->get(CV_CAP_PROP_FRAME_HEIGHT); else return 0; } int mitk::USImageVideoSource::GetImageWidth() { if (m_VideoCapture) return m_VideoCapture->get(CV_CAP_PROP_FRAME_WIDTH); else return 0; } 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; - - // We can try and correct too large boundaries - if (bottomRightX > m_VideoCapture->get(CV_CAP_PROP_FRAME_WIDTH)) bottomRightX = m_VideoCapture->get(CV_CAP_PROP_FRAME_WIDTH); - if (bottomRightY > m_VideoCapture->get(CV_CAP_PROP_FRAME_HEIGHT)) bottomRightY = m_VideoCapture->get(CV_CAP_PROP_FRAME_HEIGHT); - - // Nothing to save, throw an exception - if (topLeftX > bottomRightX) mitkThrow() << "Invalid boundaries supplied to USImageVideoSource::SetRegionOfInterest()"; - if (topLeftY > bottomRightY) mitkThrow() << "Invalid boundaries supplied to USImageVideoSource::SetRegionOfInterest()"; - - m_CropFilter->SetCropRegion(cv::Rect(topLeftX, topLeftY, bottomRightX - topLeftX, bottomRightY - topLeftY)); + m_CropFilter->SetCropRegion(topLeftX, topLeftY, bottomRightX, bottomRightY); m_IsCropped = true; - } void mitk::USImageVideoSource::RemoveRegionOfInterest(){ m_IsCropped = false; } mitk::USImage::Pointer mitk::USImageVideoSource::GetNextImage() { // Loop video if necessary if (m_VideoCapture->get(CV_CAP_PROP_POS_AVI_RATIO) >= 0.99 ) m_VideoCapture->set(CV_CAP_PROP_POS_AVI_RATIO, 0); // Setup pointers cv::Mat image; cv::Mat buffer; // Retrieve image *m_VideoCapture >> image; // get a new frame from camera // If region of interest was set, crop image if ( m_IsCropped ) { m_CropFilter->filterImage(image); } // If this source is set to deliver greyscale images, convert it if (m_IsGreyscale) { m_GrayscaleFilter->filterImage(image); } // Execute filter, if an additional filter is specified if ( m_ImageFilter.IsNotNull() ) { m_ImageFilter->filterImage(image); } // Convert to MITK-Image IplImage ipl_img = image; this->m_OpenCVToMitkFilter->SetOpenCVImage(&ipl_img); this->m_OpenCVToMitkFilter->Update(); // OpenCVToMitkImageFilter returns a standard mitk::image. We then transform it into an USImage mitk::USImage::Pointer result = mitk::USImage::New(this->m_OpenCVToMitkFilter->GetOutput()); // Clean up buffer.release(); image.release(); return result; } void mitk::USImageVideoSource::OverrideResolution(int width, int height){ this->m_ResolutionOverrideHeight = height; this->m_ResolutionOverrideWidth = width; if (m_VideoCapture != 0) { m_VideoCapture->set(CV_CAP_PROP_FRAME_WIDTH, width); m_VideoCapture->set(CV_CAP_PROP_FRAME_HEIGHT, height); } } diff --git a/Modules/US/USFilters/mitkUSImageVideoSource.h b/Modules/US/USFilters/mitkUSImageVideoSource.h index 7ce8377f4a..79dc68c030 100644 --- a/Modules/US/USFilters/mitkUSImageVideoSource.h +++ b/Modules/US/USFilters/mitkUSImageVideoSource.h @@ -1,160 +1,155 @@ /*=================================================================== 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_ // ITK #include // MITK #include "mitkUSImage.h" #include "mitkOpenCVToMitkImageFilter.h" #include "Commands/mitkConvertGrayscaleOpenCVImageFilter.h" #include "Commands/mitkCropOpenCVImageFilter.h" // OpenCV #include namespace mitk { /**Documentation * \brief This class can be pointed to a video file or a videodevice and delivers USImages. * * Images are in color by default, but can be set to greyscale via SetColorOutput(false), * which significantly improves performance. * * Images can also be cropped to a region of interest, further increasing performance. * * \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 color 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 cached file in a device. */ mitk::USImage::Pointer GetNextImage(); /** * \brief This is a workaround for a problem that happens with some video device drivers. * * If you encounter OpenCV Warnings that buffer sizes do not match while calling getNextFrame, * then do the following: Using the drivers control panel to force a certain resolution, then call * this method with the same Dimensions after opening the device. */ void OverrideResolution(int width, int height); // Getter & Setter itkGetMacro(IsVideoReady, bool); itkGetMacro(ResolutionOverride, bool); itkSetMacro(ResolutionOverride, bool); itkGetMacro(IsGreyscale,bool); itkGetMacro(ResolutionOverrideWidth,int); itkGetMacro(ResolutionOverrideHeight,int); int GetImageHeight(); int GetImageWidth(); itkGetMacro(ImageFilter, mitk::AbstractOpenCVImageFilter::Pointer); itkSetMacro(ImageFilter, mitk::AbstractOpenCVImageFilter::Pointer); protected: USImageVideoSource(); virtual ~USImageVideoSource(); /** * \brief The source of the video, managed internally */ cv::VideoCapture* m_VideoCapture; /** * \brief If true, a frame can be grabbed anytime. */ bool m_IsVideoReady; /** * \brief If true, image output will be greyscale. */ bool m_IsGreyscale; /** - * \brief If true, image will be cropped according to settings of crop filter. - */ - bool m_IsCropped; - /** - * \brief If values inside are nonzero, this rectangle will be cropped from the stream and used as an output. - * Used to mark Region of Interest. + * \brief If true, image will be cropped according to settings of crop filter. */ - cv::Rect m_CropRegion; + bool m_IsCropped; /** * \brief Used to convert from OpenCV Images to MITK Images. */ mitk::OpenCVToMitkImageFilter::Pointer m_OpenCVToMitkFilter; /** * These Variables determined whether Resolution Override is on, what dimensions to use. */ int m_ResolutionOverrideWidth; int m_ResolutionOverrideHeight; bool m_ResolutionOverride; /** * \brief Filter is executed during mitk::USImageVideoSource::GetNextImage(). */ AbstractOpenCVImageFilter::Pointer m_ImageFilter; ConvertGrayscaleOpenCVImageFilter::Pointer m_GrayscaleFilter; CropOpenCVImageFilter::Pointer m_CropFilter; }; } // namespace mitk #endif /* MITKUSImageVideoSource_H_HEADER_INCLUDED_ */