diff --git a/Modules/US/USFilters/mitkUSImageVideoSource.cpp b/Modules/US/USFilters/mitkUSImageVideoSource.cpp index 937e26d92c..016b5ebdb9 100644 --- a/Modules/US/USFilters/mitkUSImageVideoSource.cpp +++ b/Modules/US/USFilters/mitkUSImageVideoSource.cpp @@ -1,148 +1,148 @@ /*=================================================================== 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_VideoCapture = new cv::VideoCapture(); m_IsVideoReady = false; - m_IsGreyscale = true; + m_IsGreyscale = false; this->m_OpenCVToMitkFilter = mitk::OpenCVToMitkImageFilter::New(); int m_ResolutionOverrideWidth = 0; int m_ResolutionOverrideHeight = 0; bool m_ResolutionOverride = 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; } 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 (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() { // 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 is set, crop image if (m_CropRegion.width > 0){ buffer = image(m_CropRegion); image = buffer; } // 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::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 0f72c66580..6205cd792e 100644 --- a/Modules/US/USFilters/mitkUSImageVideoSource.h +++ b/Modules/US/USFilters/mitkUSImageVideoSource.h @@ -1,133 +1,139 @@ /*=================================================================== 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" // 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 + * \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 + * \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" + * \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 + * \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); 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 values inside are nonzero, this rectangle will be cropped from the stream and used as an output. * Used to mark Region of Interest. */ cv::Rect m_CropRegion; /** * \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; }; } // namespace mitk #endif /* MITKUSImageVideoSource_H_HEADER_INCLUDED_ */ diff --git a/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.cpp b/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.cpp index cbf3c3eaaa..24420ec71b 100644 --- a/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.cpp +++ b/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.cpp @@ -1,165 +1,167 @@ /*=================================================================== 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. ===================================================================*/ //#define _USE_MATH_DEFINES #include //QT headers //mitk headers //itk headers const std::string QmitkUSNewVideoDeviceWidget::VIEW_ID = "org.mitk.views.QmitkUSNewVideoDeviceWidget"; QmitkUSNewVideoDeviceWidget::QmitkUSNewVideoDeviceWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f) { m_Controls = NULL; CreateQtPartControl(this); } QmitkUSNewVideoDeviceWidget::~QmitkUSNewVideoDeviceWidget() { } //////////////////// INITIALIZATION ///////////////////// void QmitkUSNewVideoDeviceWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkUSNewVideoDeviceWidgetControls; m_Controls->setupUi(parent); this->CreateConnections(); } } void QmitkUSNewVideoDeviceWidget::CreateConnections() { if ( m_Controls ) { connect( m_Controls->m_BtnDone, SIGNAL(clicked()), this, SLOT(OnClickedDone()) ); connect( m_Controls->m_BtnCancel, SIGNAL(clicked()), this, SLOT(OnClickedCancel()) ); connect( m_Controls->m_RadioDeviceSource, SIGNAL(clicked()), this, SLOT(OnDeviceTypeSelection()) ); connect( m_Controls->m_RadioFileSource, SIGNAL(clicked()), this, SLOT(OnDeviceTypeSelection()) ); } // Hide & show stuff m_Controls->m_FilePathSelector->setVisible(false); } ///////////// Methods & Slots Handling Direct Interaction ///////////////// void QmitkUSNewVideoDeviceWidget::OnClickedDone(){ m_Active = false; MITK_INFO << "NewDeviceWidget: ClickedDone()"; // Assemble Metadata mitk::USImageMetadata::Pointer metadata = mitk::USImageMetadata::New(); metadata->SetDeviceComment(m_Controls->m_Comment->text().toStdString()); metadata->SetDeviceModel(m_Controls->m_Model->text().toStdString()); metadata->SetDeviceManufacturer(m_Controls->m_Manufacturer->text().toStdString()); metadata->SetProbeName(m_Controls->m_Probe->text().toStdString()); metadata->SetZoom(m_Controls->m_Zoom->text().toStdString()); // Create Device mitk::USVideoDevice::Pointer newDevice; if (m_Controls->m_RadioDeviceSource->isChecked()){ int deviceID = m_Controls->m_DeviceSelector->value(); newDevice = mitk::USVideoDevice::New(deviceID, metadata); } else { std::string filepath = m_Controls->m_FilePathSelector->text().toStdString(); newDevice = mitk::USVideoDevice::New(filepath, metadata); } + // Set Video Options + newDevice->GetSource()->SetColorOutput(! m_Controls->m_CheckGreyscale->isChecked()); + // If Resolution override is activated, apply it - if (m_Controls->m_ResolutionOverride->isChecked()) + if (m_Controls->m_CheckResolutionOverride->isChecked()) { int width = m_Controls->m_ResolutionWidth->value(); int height = m_Controls->m_ResolutionHeight->value(); newDevice->GetSource()->OverrideResolution(width, height); newDevice->GetSource()->SetResolutionOverride(true); } - newDevice->Connect(); emit Finished(); } void QmitkUSNewVideoDeviceWidget::OnClickedCancel(){ m_TargetDevice = 0; m_Active = false; MITK_INFO << "NewDeviceWidget: OnClickedCancel()"; emit Finished(); } void QmitkUSNewVideoDeviceWidget::OnDeviceTypeSelection(){ m_Controls->m_FilePathSelector->setVisible(m_Controls->m_RadioFileSource->isChecked()); m_Controls->m_DeviceSelector->setVisible(m_Controls->m_RadioDeviceSource->isChecked()); } ///////////////// Methods & Slots Handling Logic ////////////////////////// void QmitkUSNewVideoDeviceWidget::EditDevice(mitk::USDevice::Pointer device) { // If no VideoDevice is given, throw an exception if (device->GetDeviceClass().compare("org.mitk.modules.us.USVideoDevice") != 0){ // TODO Alert if bad path mitkThrow() << "NewVideoDevcieWidget recieved an incompatible Device Type to edit. Devicetype was: " << device->GetDeviceClass(); } MITK_INFO << "NewDeviceWidget: EditDevice()"; m_TargetDevice = static_cast (device.GetPointer()); m_Active = true; } void QmitkUSNewVideoDeviceWidget::CreateNewDevice() { MITK_INFO << "NewDeviceWidget: CreateNewDevice()"; m_TargetDevice = 0; InitFields(mitk::USImageMetadata::New()); m_Active = true; } /////////////////////// HOUSEHOLDING CODE /////////////////////////////// QListWidgetItem* QmitkUSNewVideoDeviceWidget::ConstructItemFromDevice(mitk::USDevice::Pointer device){ QListWidgetItem *result = new QListWidgetItem; std::string text = device->GetDeviceManufacturer() + "|" + device->GetDeviceModel(); result->setText(text.c_str()); return result; } void QmitkUSNewVideoDeviceWidget::InitFields(mitk::USImageMetadata::Pointer metadata){ this->m_Controls->m_Manufacturer->setText (metadata->GetDeviceManufacturer().c_str()); this->m_Controls->m_Model->setText (metadata->GetDeviceModel().c_str()); this->m_Controls->m_Comment->setText (metadata->GetDeviceComment().c_str()); this->m_Controls->m_Probe->setText (metadata->GetProbeName().c_str()); this->m_Controls->m_Zoom->setText (metadata->GetZoom().c_str()); } diff --git a/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidgetControls.ui b/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidgetControls.ui index 1eb88186ed..d9458881a4 100644 --- a/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidgetControls.ui +++ b/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidgetControls.ui @@ -1,274 +1,292 @@ QmitkUSNewVideoDeviceWidgetControls 0 0 405 - 528 + 569 0 0 QmitkUSNewVideoDeviceWidget Metadata: 50 false true Device Information: Manufacturer Model Comment true Probe Information: Probe Zoom GroupBox: -1 10 -1 From Device: true From File: - - - - Add Device - - - - + Cancel - + Override: - If you encounter problems with devices (e.g. Images of uniform color and error messages in the log window), then try to set the resolution externally using the devices driver panel, and then enter the same resolution here. + If you encounter problems with devices (e.g. Images of uniform color and error messages in the log window), then try to set the resolution externally using the device's driver panel and then enter the same resolution here. true - + Enable Resolution Override 10 2048 10 640 10 2048 10 480 Width: Height: - + Qt::Vertical 20 40 + + + + Add Device + + + + + + + Video Options: + + + + + + Greyscale Image (Significantly faster) + + + true + + + + + + m_Manufacturer m_Model m_Comment m_Probe m_Zoom m_RadioDeviceSource m_DeviceSelector m_RadioFileSource m_FilePathSelector - m_BtnDone m_BtnCancel - m_ResolutionOverride + m_CheckResolutionOverride m_ResolutionWidth m_ResolutionHeight