diff --git a/Modules/US/USFilters/mitkUSImageVideoSource.cpp b/Modules/US/USFilters/mitkUSImageVideoSource.cpp index 442123b4f0..f6e11a8a01 100644 --- a/Modules/US/USFilters/mitkUSImageVideoSource.cpp +++ b/Modules/US/USFilters/mitkUSImageVideoSource.cpp @@ -1,128 +1,125 @@ /*=================================================================== 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_IsGreyscale = true; this->m_OpenCVToMitkFilter = mitk::OpenCVToMitkImageFilter::New(); } - mitk::USImageVideoSource::~USImageVideoSource() { } - void mitk::USImageVideoSource::SetVideoFileInput(std::string path) { - m_OpenCVVideoSource = mitk::OpenCVVideoSource::New(); - - 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(); + m_VideoCapture = new cv::VideoCapture(path.c_str()); + if(!m_VideoCapture->isOpened()) // check if we succeeded + m_IsVideoReady = false; + else + m_IsVideoReady = true; } void mitk::USImageVideoSource::SetCameraInput(int deviceID) { - 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(); + m_VideoCapture = new cv::VideoCapture(deviceID); + if(!m_VideoCapture->isOpened()) // check if we succeeded + m_IsVideoReady = false; + else + m_IsVideoReady = true; } 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(); + // 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 (bottomRightX > 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_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 + // 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; - //Get dimensions and init rgb - int width = m_OpenCVVideoSource->GetImageWidth(); - int height = m_OpenCVVideoSource->GetImageHeight(); - - // Get Frame from Source - m_OpenCVVideoSource->FetchFrame(); - image = m_OpenCVVideoSource->GetImage(); - + // Retrieve image + *m_VideoCapture >> image; // get a new frame from camera + // 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 this source is set to deliver greyscale images, convert it if (m_IsGreyscale) { cv::cvtColor(image, buffer, CV_RGB2GRAY, 1); image = buffer; } + + // 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(0)); return result; } + +void mitk::USImageVideoSource::ForceDimensions(int width, int height){ + 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 f527be52ff..00d71289cd 100644 --- a/Modules/US/USFilters/mitkUSImageVideoSource.h +++ b/Modules/US/USFilters/mitkUSImageVideoSource.h @@ -1,99 +1,109 @@ /*=================================================================== 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 "mitkOpenCVVideoSource.h" #include "mitkOpenCVToMitkImageFilter.h" +// OpenCV +#include + 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. + * \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 ForceDimensions(int width, int height); // Getter & Setter - itkGetMacro(OpenCVVideoSource, mitk::OpenCVVideoSource::Pointer); - itkSetMacro(OpenCVVideoSource, mitk::OpenCVVideoSource::Pointer); itkGetMacro(IsVideoReady, bool); protected: USImageVideoSource(); virtual ~USImageVideoSource(); /** * \brief The source of the video */ - mitk::OpenCVVideoSource::Pointer m_OpenCVVideoSource; - - bool m_IsVideoReady; - bool m_IsGreyscale; - cv::Rect m_CropRegion; - mitk::OpenCVToMitkImageFilter::Pointer m_OpenCVToMitkFilter; - + cv::VideoCapture* m_VideoCapture; + bool m_IsVideoReady; + bool m_IsGreyscale; + cv::Rect m_CropRegion; + mitk::OpenCVToMitkImageFilter::Pointer m_OpenCVToMitkFilter; }; } // namespace mitk #endif /* MITKUSImageVideoSource_H_HEADER_INCLUDED_ */ diff --git a/Modules/US/USModel/mitkUSVideoDevice.h b/Modules/US/USModel/mitkUSVideoDevice.h index 6008bacaef..7a685ee2dd 100644 --- a/Modules/US/USModel/mitkUSVideoDevice.h +++ b/Modules/US/USModel/mitkUSVideoDevice.h @@ -1,127 +1,129 @@ /*=================================================================== 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 MITKUSVideoDevice_H_HEADER_INCLUDED_ #define MITKUSVideoDevice_H_HEADER_INCLUDED_ #include #include #include "mitkUSDevice.h" #include #include "mitkUSImageVideoSource.h" namespace mitk { /**Documentation * \brief A VideoDevice is the common class for video only devices. They capture Video Input either from * a file or from a device, and transform the output into an mitkUSImage with attached Metadata. * This simple implementation does only capture and display 2D Images without cropping or registration. * One can simply inherit from this class and overwrite the handle2D and handle 3Dmethods to get full access to the data * \ingroup US */ class MitkUS_EXPORT USVideoDevice : public mitk::USDevice { public: mitkClassMacro(USVideoDevice, mitk::USDevice); // To open a device (DeviceID, Manufacturer, Model) mitkNewMacro3Param(Self, int, std::string, std::string); // To open A VideoFile (Path, Manufacturer, Model) mitkNewMacro3Param(Self, std::string, std::string, std::string); // To open a device (DeviceID, Metadata) mitkNewMacro2Param(Self, int, mitk::USImageMetadata::Pointer); // To open A VideoFile (Path, Metadata) mitkNewMacro2Param(Self, std::string, mitk::USImageMetadata::Pointer); /** * \brief Returns the qualified name of this class. Be sure to override this when inheriting from VideoDevice! */ virtual std::string GetDeviceClass(); void GenerateData(); + itkGetMacro(Source, mitk::USImageVideoSource::Pointer); + protected: /** * \brief Creates a new device that will deliver USImages taken from a video device. * under windows, try -1 for device number, which will grab the first available one * (Open CV functionality) */ USVideoDevice(int videoDeviceNumber, std::string manufacturer, std::string model); /** * \brief Creates a new device that will deliver USImages taken from a video file. */ USVideoDevice(std::string videoFilePath, std::string manufacturer, std::string model); /** * \brief Creates a new device that will deliver USImages taken from a video device. * under windows, try -1 for device number, which will grab the first available one * (Open CV functionality) */ USVideoDevice(int videoDeviceNumber, mitk::USImageMetadata::Pointer metadata); /** * \brief Creates a new device that will deliver USImages taken from a video file. */ USVideoDevice(std::string videoFilePath, mitk::USImageMetadata::Pointer metadata); virtual ~USVideoDevice(); /** * \brief Is called during the connection process. * Returns true if successful and false if unsuccessful. Additionally, you may throw an exception to clarify what went wrong. */ virtual bool OnConnection(); /** * \brief Is called during the disconnection process. * Returns true if successful and false if unsuccessful. Additionally, you may throw an exception to clarify what went wrong. */ virtual bool OnDisconnection(); /** * \brief Is called during the activation process. After this method is finsihed, the device should be generating images */ virtual bool OnActivation(); /** * \brief Is called during the deactivation process. After a call to this method the device should still be connected, but not producing images anymore. */ virtual void OnDeactivation(); /** * \brief The image source that we use to aquire data */ mitk::USImageVideoSource::Pointer m_Source; /** * \brief True, if this source plays back a file, false if it recieves data from a device */ bool m_SourceIsFile; /** * \brief The device id to connect to. Undefined, if m_SourceIsFile == true; */ int m_DeviceID; /** * \brief The Filepath id to connect to. Undefined, if m_SourceIsFile == false; */ std::string m_FilePath; }; } // namespace mitk #endif