Medical Imaging Interaction Toolkit  2018.4.99-a3d2e8fb
Medical Imaging Interaction Toolkit
QmitkOpenCVVideoControls.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
14 #include <QmitkVideoBackground.h>
15 #include <QmitkRenderWindow.h>
16 #include <mitkOpenCVVideoSource.h>
17 
19 
20 class QmitkOpenCVVideoControlsPrivate
21 {
22 public:
23 
24  QmitkOpenCVVideoControlsPrivate(QmitkOpenCVVideoControls* q, const std::string& id)
25  : q(q)
26  , m_Id(id)
27  {}
28 
33 
35 
39  std::string m_Id;
40  void ToPropertyList();
41  void FromPropertyList();
42 };
43 
45  , QmitkRenderWindow* _RenderWindow
46  , QWidget * parent, Qt::WindowFlags f)
47  : QWidget(parent, f)
48  , m_VideoBackground(nullptr)
49  , m_RenderWindow(nullptr)
50  , m_VideoSource(nullptr)
51  , m_Controls(new Ui::QmitkOpenCVVideoControls)
52  , m_SliderCurrentlyMoved(false)
53  , d(new QmitkOpenCVVideoControlsPrivate(this, "QmitkOpenCVVideoControls"))
54 {
55  m_Controls->setupUi(this);
56  m_Controls->FileChooser->SetFileMustExist(true);
57  m_Controls->FileChooser->SetSelectDir(false);
58 
59  this->SetRenderWindow(_RenderWindow);
60  this->SetVideoBackground(_VideoBackground);
61  d->FromPropertyList();
62 
63  mitk::IPersistenceService* persistenceService = d->GetPersistenceService();
64 
65  if (persistenceService != nullptr)
66  {
67  persistenceService->AddPropertyListReplacedObserver(this);
68  }
69  else
70  {
71  MITK_WARN << "No Persistence Service available in constructor";
72  }
73 }
74 
76 {
77  if (m_VideoSource != nullptr && m_VideoSource->IsCapturingEnabled())
78  {
79  this->Stop(); // emulate stop
80  }
81 
82  mitk::IPersistenceService* persistenceService = d->GetPersistenceService();
83  if (persistenceService != nullptr)
84  {
85  persistenceService->RemovePropertyListReplacedObserver(this);
86  }
87  else
88  {
89  MITK_WARN << "No Persistence Service available in destructor";
90  }
91 
92  d->ToPropertyList();
93 }
94 
96 {
97  //Fixes T23169
99 }
100 
102 {
103  m_Controls->GrabbingDevicePanel->setEnabled(true);
104  m_Controls->VideoFilePanel->setEnabled(false);
105 }
106 
108 {
109  m_Controls->GrabbingDevicePanel->setEnabled(false);
110  m_Controls->VideoFilePanel->setEnabled(true);
111  m_Controls->FileChooser->setEnabled(true);
112 }
113 
115 {
116  m_SliderCurrentlyMoved = true;
117  // temporary pause the video while sliding
120 }
121 
123 {
124  double progressRatio = static_cast<double>(m_Controls->VideoProgressSlider->value())
125  / static_cast<double>(m_Controls->VideoProgressSlider->maximum());
126  m_VideoSource->SetVideoCaptureProperty(CV_CAP_PROP_POS_FRAMES, progressRatio*m_VideoSource->GetVideoCaptureProperty(CV_CAP_PROP_FRAME_COUNT));
127 
128  // resume the video ( if it was not paused by the user)
129  if (m_VideoSource->GetCapturePaused() && m_Controls->PlayButton->isChecked())
131  m_SliderCurrentlyMoved = false;
132 }
133 
135 {
136  MITK_INFO << "repeat video clicked";
137  m_VideoSource->SetRepeatVideo(checked);
138 }
139 
141 {
142  MITK_INFO << "play button clicked";
143  if (checked)
144  {
145  this->Play();
146  }
147  else
148  {
149  // show pause button
150  this->IsPlaying(true);
152  }
153 }
154 
156 {
157  this->Stop();
158 }
159 
161 {
163  {
164  this->IsPlaying(false);
166  }
167  else
168  {
169  if (m_Controls->UseGrabbingDeviceButton->isChecked())
170  {
171  m_VideoSource->SetVideoCameraInput(m_Controls->GrabbingDeviceNumber->text().toInt(), false);
172  m_Controls->VideoFileControls->setEnabled(false);
173  }
174  else
175  {
176  m_VideoSource->SetVideoFileInput(m_Controls->FileChooser->GetFile().c_str(), m_Controls->RepeatVideoButton->isChecked(), false);
177  m_VideoSource->SetRepeatVideo(m_Controls->RepeatVideoButton->isChecked());
178  m_Controls->VideoProgressSlider->setValue(0);
179  }
180 
182 
184  {
185  MITK_ERROR << "Video could not be initialized!";
186  m_Controls->PlayButton->setChecked(false);
187  }
188  else
189  {
190  int hertz = m_Controls->UpdateRate->text().toInt();
191  int updateTime = itk::Math::Round<int, double>(1000.0 / hertz);
192 
193  // resets the whole background
194  m_VideoBackground->SetTimerDelay(updateTime);
196  this->connect(m_VideoBackground, SIGNAL(NewFrameAvailable(mitk::VideoSource*))
197  , this, SLOT(NewFrameAvailable(mitk::VideoSource*)));
200 
202  this->m_Controls->StopButton->setEnabled(true);
203  // show video file controls
204  if (m_Controls->UseVideoFileButton->isChecked())
205  {
206  m_Controls->VideoFileControls->setEnabled(true);
207  m_Controls->RepeatVideoButton->setEnabled(true);
208  m_Controls->VideoProgressSlider->setEnabled(true);
209  }
210  // show pause button
211  this->IsPlaying(false);
212  // disable other controls
213  m_Controls->GrabbingDevicePanel->setEnabled(false);
214  m_Controls->VideoFilePanel->setEnabled(false);
215  m_Controls->UseGrabbingDeviceButton->setEnabled(false);
216  m_Controls->UseVideoFileButton->setEnabled(false);
217  m_Controls->UpdateRatePanel->setEnabled(false);
218  }
219  }
220 }
221 
223 {
224  // disable video file controls, stop button and show play button again
225  m_Controls->UseGrabbingDeviceButton->setEnabled(true);
226  m_Controls->UseVideoFileButton->setEnabled(true);
227  if (m_Controls->UseGrabbingDeviceButton->isChecked())
229  else
231 
232  m_Controls->UpdateRatePanel->setEnabled(true);
233  m_Controls->VideoProgressSlider->setValue(0);
234  m_Controls->VideoFileControls->setEnabled(false);
235  this->m_Controls->StopButton->setEnabled(false);
236  this->IsPlaying(true);
237 
238  if (m_VideoBackground)
239  {
241 
242  if (m_RenderWindow)
244 
245  this->disconnect(m_VideoBackground, SIGNAL(NewFrameAvailable(mitk::VideoSource*))
246  , this, SLOT(NewFrameAvailable(mitk::VideoSource*)));
247  }
248  if (m_VideoSource != nullptr)
250 }
251 
253 {
254  this->Stop();
255 }
256 
258 {
259  if (paused)
260  {
261  m_Controls->PlayButton->setText("Play");
262  m_Controls->PlayButton->setIcon(QIcon(":/OpenCVVideoSupportUI/media-playback-start.png"));
263  m_Controls->PlayButton->setChecked(false);
264  }
265  else
266  {
267  m_Controls->PlayButton->setText("Pause");
268  m_Controls->PlayButton->setIcon(QIcon(":/OpenCVVideoSupportUI/media-playback-pause.png"));
269  m_Controls->PlayButton->setChecked(true);
270  }
271 }
272 
274 {
277  {
278  m_Controls->VideoProgressSlider->setValue(itk::Math::Round<int, double>(m_VideoSource->GetVideoCaptureProperty(CV_CAP_PROP_POS_FRAMES)
279  *(1 / m_VideoSource->GetVideoCaptureProperty(CV_CAP_PROP_FRAME_COUNT)
280  *m_Controls->VideoProgressSlider->maximum())));
281  }
282 }
283 
285 {
286  if (m_Controls->RepeatVideoButton->isChecked())
287  {
288  this->Reset();
289  this->Play();
290  }
291  else
292  {
293  this->Stop();
294  }
295 }
296 
298 {
299  if (m_RenderWindow == _RenderWindow)
300  return;
301 
302  // In Reset() m_MultiWidget is used, set it to 0 now for avoiding errors
303  if (_RenderWindow == nullptr)
304  m_RenderWindow = nullptr;
305  this->Reset();
306 
307  m_RenderWindow = _RenderWindow;
308 
309  if (m_RenderWindow == nullptr)
310  {
311  this->setEnabled(false);
312  }
313  else
314  {
315  this->setEnabled(true);
316  }
317 }
318 
320 {
321  return m_RenderWindow;
322 }
323 
325 {
326  if (m_VideoBackground == _VideoBackground)
327  return;
328 
329  if (m_VideoBackground != nullptr)
330  this->disconnect(m_VideoBackground, SIGNAL(destroyed(QObject*))
331  , this, SLOT(QObjectDestroyed(QObject*)));
332 
333  this->Reset();
334 
335  m_VideoBackground = _VideoBackground;
336 
337  if (m_VideoBackground == nullptr)
338  {
339  m_VideoSource = nullptr;
340  MITK_WARN << "m_MultiWidget is 0";
341  this->setEnabled(false);
342  }
343  else
344  {
345  this->setEnabled(true);
347  // preset form entries
348  if (m_VideoSource != nullptr)
349  {
350  if (!m_VideoSource->GetVideoFileName().empty())
351  {
352  m_Controls->FileChooser->SetFile(m_VideoSource->GetVideoFileName());
354  }
355  else if (m_VideoSource->GetGrabbingDeviceNumber() >= 0)
356  m_Controls->GrabbingDeviceNumber->setValue(m_VideoSource->GetGrabbingDeviceNumber());
357 
358  m_Controls->UpdateRate->setValue(m_VideoBackground->GetTimerDelay());
359 
360  this->connect(m_VideoBackground, SIGNAL(destroyed(QObject*))
361  , this, SLOT(QObjectDestroyed(QObject*)));
362  }
363  else
364  {
365  MITK_WARN << "m_VideoSource is 0";
366  this->setEnabled(false);
367  }
368  }
369 }
370 
372 {
373  return m_VideoBackground;
374 }
375 
376 void QmitkOpenCVVideoControls::QObjectDestroyed(QObject * obj /*= 0 */)
377 {
378  if (m_VideoBackground == obj)
379  {
380  m_VideoSource = nullptr;
381  this->SetVideoBackground(nullptr);
382  }
383 }
384 
385 void QmitkOpenCVVideoControlsPrivate::ToPropertyList()
386 {
387  mitk::IPersistenceService* persistenceService = this->GetPersistenceService();
388 
389  if (persistenceService != nullptr)
390  {
391  mitk::PropertyList::Pointer propList = persistenceService->GetPropertyList(m_Id);
392  propList->Set("deviceType", q->m_Controls->UseGrabbingDeviceButton->isChecked() ? 0 : 1);
393  propList->Set("grabbingDeviceNumber", q->m_Controls->GrabbingDeviceNumber->value());
394  propList->Set("updateRate", q->m_Controls->UpdateRate->value());
395  propList->Set("repeatVideo", q->m_Controls->RepeatVideoButton->isChecked());
396  }
397  else
398  {
399  MITK_WARN << "Persistence Service not available.";
400  }
401 }
402 
403 void QmitkOpenCVVideoControlsPrivate::FromPropertyList()
404 {
405  mitk::IPersistenceService* persistenceService = this->GetPersistenceService();
406 
407  if (persistenceService != nullptr)
408  {
409  mitk::PropertyList::Pointer propList = persistenceService->GetPropertyList(m_Id);
410 
411  bool repeatVideo = false;
412  propList->Get("repeatVideo", repeatVideo);
413  q->m_Controls->RepeatVideoButton->setChecked(repeatVideo);
414 
415  int updateRate = 25;
416  propList->Get("updateRate", updateRate);
417  q->m_Controls->UpdateRate->setValue(updateRate);
418 
419  int grabbingDeviceNumber = 0;
420  propList->Get("grabbingDeviceNumber", grabbingDeviceNumber);
421  q->m_Controls->GrabbingDeviceNumber->setValue(grabbingDeviceNumber);
422 
423  int deviceType = 0;
424  propList->Get("deviceType", deviceType);
425  if (deviceType == 0)
426  {
427  q->m_Controls->UseGrabbingDeviceButton->setChecked(true);
428  }
429  else
430  {
431  q->m_Controls->UseVideoFileButton->setChecked(true);
432  }
433  }
434  else
435  {
436  MITK_WARN << "Persistence Service not available.";
437  }
438 }
439 
440 void QmitkOpenCVVideoControls::AfterPropertyListReplaced(const std::string& id, mitk::PropertyList* /*propertyList*/)
441 {
442  if (id == d->m_Id)
443  d->FromPropertyList();
444 }
QmitkRenderWindow * GetRenderWindow() const
virtual int SetVideoCaptureProperty(int property_id, double value)
virtual mitk::PropertyList::Pointer GetPropertyList(std::string &id, bool *existed=nullptr)=0
void on_VideoProgressSlider_valueChanged(int value)
virtual void AddPropertyListReplacedObserver(PropertyListReplacedObserver *observer)=0
void RemoveRenderWindow(vtkRenderWindow *renderWindow)
removes a renderwindow = disables video background there
void on_UseGrabbingDeviceButton_clicked(bool checked=false)
#define MITK_INFO
Definition: mitkLogMacros.h:18
QmitkVideoBackground * GetVideoBackground() const
#define MITK_ERROR
Definition: mitkLogMacros.h:20
virtual short GetGrabbingDeviceNumber() const
void Disable()
disables visualization of the video.
QmitkOpenCVVideoControls(QmitkVideoBackground *_VideoBackground, QmitkRenderWindow *_RenderWindow, QWidget *parent=nullptr, Qt::WindowFlags f=nullptr)
void NewFrameAvailable(mitk::VideoSource *videoSource)
virtual double GetVideoCaptureProperty(int property_id)
void on_StopButton_clicked(bool checked=false)
void AddRenderWindow(vtkRenderWindow *renderWindow)
add a RenderWindow in which the video is displayed. -> must be initialized before enabling the backgr...
void EndOfVideoSourceReached(mitk::VideoSource *videoSource)
Key-value list holding instances of BaseProperty.
Ui::QmitkOpenCVVideoControls * m_Controls
void NewOpenCVFrameAvailable(const IplImage *)
virtual void SetRepeatVideo(bool _arg)
void QObjectDestroyed(QObject *obj=nullptr)
Offers widgets to play/pause/stop a video on a certain render window with the use of an !initialized!...
#define MITK_WARN
Definition: mitkLogMacros.h:19
virtual void SetVideoFileInput(const char *filename, bool repeatVideo, bool useCVCAMLib=false)
virtual void SetVideoCameraInput(int cameraindex, bool useCVCAMLib=false)
void SetVideoBackground(QmitkVideoBackground *_VideoBackground)
MITK implementation of the QVTKWidget.
virtual bool GetCapturePaused() const
void on_PlayButton_clicked(bool checked=false)
mitk::VideoSource * GetVideoSource()
virtual const IplImage * GetCurrentFrame()
#define PERSISTENCE_GET_SERVICE_METHOD_MACRO
void on_UseVideoFileButton_clicked(bool checked=false)
virtual bool IsCapturingEnabled() const
void SetTimerDelay(int ms)
sets the update rate of the video in milli seconds, by default 25.
void AfterPropertyListReplaced(const std::string &id, mitk::PropertyList *propertyList) override
virtual std::string GetVideoFileName() const
mitk::IPropertyPersistence * GetPersistenceService()
vtkRenderWindow * GetVtkRenderWindow() override
void SetRenderWindow(QmitkRenderWindow *_RenderWindow)
virtual void RemovePropertyListReplacedObserver(PropertyListReplacedObserver *observer)=0
void on_RepeatVideoButton_clicked(bool checked=false)
mitk::OpenCVVideoSource * m_VideoSource
QmitkVideoBackground * m_VideoBackground