35 #include <QCoreApplication>
38 #include <QHostAddress>
39 #include "igtlOSUtil.h"
40 #include "igtlImageMessage.h"
41 #include "igtlServerSocket.h"
42 #include "vtkImageData.h"
43 #include "vtkSmartPointer.h"
44 #include "vtkMetaImageReader.h"
45 #include "vtkImageImport.h"
46 #include "vtkLookupTable.h"
47 #include "vtkImageMapToColors.h"
48 #include "vtkMetaImageWriter.h"
57 #include <opencv2/highgui/highgui.hpp>
58 #include <opencv2/imgproc/imgproc.hpp>
66 std::vector<PropertyPtr> retval;
77 retval->setGroup(
"OpenCV");
84 bool defaultValue =
false;
86 "When starting OpenCV, print properties to console",
88 retval->setAdvanced(
true);
89 retval->setGroup(
"OpenCV");
96 retval[
"--type"] =
"OpenCV";
97 retval[
"--videoport"] = this->
getVideoPortOption(root)->getValueAsVariant().toString();
99 retval[
"--properties"] =
"1";
107 retval <<
"--videoport: video id, default=0";
108 retval <<
"--in_width: width of incoming image, default=camera";
109 retval <<
"--in_height: height of incoming image, default=camera";
110 retval <<
"--out_width: width of outgoing image, default=camera";
111 retval <<
"--out_height: width of outgoing image, default=camera";
112 retval <<
"--properties: dump image properties";
128 void GetRandomTestMatrix(igtl::Matrix4x4& matrix)
161 mAvailableImage =
false;
165 mVideoCapture.reset(
new cv::VideoCapture());
170 connect(
mSendTimer, SIGNAL(timeout()),
this, SLOT(send()));
175 this->deinitialize_local();
194 void ImageStreamerOpenCV::deinitialize_local()
198 qApp->processEvents();
199 mVideoCapture->release();
200 mVideoCapture.reset(
new cv::VideoCapture());
204 void ImageStreamerOpenCV::initialize_local()
222 QString videoSource =
mArguments[
"videoport"];
225 bool sourceIsInt =
false;
226 videoSource.toInt(&sourceIsInt);
231 mVideoCapture->open(videoport);
235 mVideoCapture->open(videoSource.toStdString().c_str());
238 if (!mVideoCapture->isOpened())
240 cerr <<
"ImageStreamerOpenCV: Failed to open a video device or video file!\n" << endl;
246 int default_width = mVideoCapture->get(CV_CAP_PROP_FRAME_WIDTH);
247 int default_height = mVideoCapture->get(CV_CAP_PROP_FRAME_HEIGHT);
252 mVideoCapture->set(CV_CAP_PROP_FRAME_WIDTH, in_width);
253 mVideoCapture->set(CV_CAP_PROP_FRAME_HEIGHT, in_height);
258 mRescaleSize.setWidth(out_width);
259 mRescaleSize.setHeight(out_height);
262 this->dumpProperties();
264 std::cout <<
"ImageStreamerOpenCV: Started streaming from openCV device "
265 << videoSource.toStdString()
266 <<
", size=(" << in_width <<
"," << in_height <<
")";
267 if (( in_width!=mRescaleSize.width() )|| (in_height!=mRescaleSize.height()))
268 std::cout <<
". Scaled to (" << mRescaleSize.width() <<
"," << mRescaleSize.height() <<
")";
270 std::cout << std::endl;
277 this->initialize_local();
282 std::cout <<
"ImageStreamerOpenCV: Failed to start streaming: Not initialized." << std::endl;
289 this->continousGrabEvent();
305 this->deinitialize_local();
308 void ImageStreamerOpenCV::dumpProperties()
311 this->dumpProperty(CV_CAP_PROP_POS_MSEC,
"CV_CAP_PROP_POS_MSEC");
312 this->dumpProperty(CV_CAP_PROP_POS_FRAMES,
"CV_CAP_PROP_POS_FRAMES");
313 this->dumpProperty(CV_CAP_PROP_POS_AVI_RATIO,
"CV_CAP_PROP_POS_AVI_RATIO");
314 this->dumpProperty(CV_CAP_PROP_FRAME_WIDTH,
"CV_CAP_PROP_FRAME_WIDTH");
315 this->dumpProperty(CV_CAP_PROP_FRAME_HEIGHT,
"CV_CAP_PROP_FRAME_HEIGHT");
316 this->dumpProperty(CV_CAP_PROP_FPS,
"CV_CAP_PROP_FPS");
317 this->dumpProperty(CV_CAP_PROP_FOURCC,
"CV_CAP_PROP_FOURCC");
318 this->dumpProperty(CV_CAP_PROP_FRAME_COUNT,
"CV_CAP_PROP_FRAME_COUNT");
319 this->dumpProperty(CV_CAP_PROP_FORMAT,
"CV_CAP_PROP_FORMAT");
320 this->dumpProperty(CV_CAP_PROP_MODE,
"CV_CAP_PROP_MODE");
321 this->dumpProperty(CV_CAP_PROP_BRIGHTNESS,
"CV_CAP_PROP_BRIGHTNESS");
322 this->dumpProperty(CV_CAP_PROP_CONTRAST,
"CV_CAP_PROP_CONTRAST");
323 this->dumpProperty(CV_CAP_PROP_SATURATION,
"CV_CAP_PROP_SATURATION");
324 this->dumpProperty(CV_CAP_PROP_HUE,
"CV_CAP_PROP_HUE");
325 this->dumpProperty(CV_CAP_PROP_GAIN,
"CV_CAP_PROP_GAIN");
326 this->dumpProperty(CV_CAP_PROP_EXPOSURE,
"CV_CAP_PROP_EXPOSURE");
327 this->dumpProperty(CV_CAP_PROP_CONVERT_RGB,
"CV_CAP_PROP_CONVERT_RGB");
329 this->dumpProperty(CV_CAP_PROP_RECTIFICATION,
"CV_CAP_PROP_RECTIFICATION");
333 void ImageStreamerOpenCV::dumpProperty(
int val, QString name)
336 double value = mVideoCapture->get(val);
338 std::cout <<
"Property " << name.toStdString() <<
" : " << mVideoCapture->get(val) << std::endl;
347 void ImageStreamerOpenCV::continousGrabEvent()
352 QMetaObject::invokeMethod(
this,
"continousGrabEvent", Qt::QueuedConnection);
355 void ImageStreamerOpenCV::grab()
358 if (!mVideoCapture->isOpened())
364 mVideoCapture->grab();
365 mLastGrabTime = QDateTime::currentDateTime();
366 mAvailableImage =
true;
371 void ImageStreamerOpenCV::send()
375 if (!mAvailableImage)
381 package->mIgtLinkImageMessage = this->getImageMessage();
383 mAvailableImage =
false;
395 if (!mVideoCapture->isOpened())
398 QTime start = QTime::currentTime();
400 cv::Mat frame_source;
402 if (!mVideoCapture->retrieve(frame_source, 0))
405 if (this->thread() == QCoreApplication::instance()->thread() && !
mSender)
407 cv::imshow(
"ImageStreamerOpenCV", frame_source);
413 igtl::TimeStamp::Pointer timestamp;
414 timestamp = igtl::TimeStamp::New();
416 double grabTime = 1.0 / 1000 * (double) mLastGrabTime.toMSecsSinceEpoch();
417 timestamp->SetTime(grabTime);
418 static QDateTime lastlastGrabTime = mLastGrabTime;
421 lastlastGrabTime = mLastGrabTime;
423 cv::Mat frame = frame_source;
424 if (( frame.cols!=mRescaleSize.width() )|| (frame.rows!=mRescaleSize.height()))
426 cv::resize(frame_source, frame, cv::Size(mRescaleSize.width(), mRescaleSize.height()), 0, 0, CV_INTER_LINEAR);
435 size[0] = frame.cols;
436 size[1] = frame.rows;
445 if (frame.channels() == 3 || frame.channels() == 4)
447 scalarType = IGTLinkImageMessage::TYPE_UINT32;
449 else if (frame.channels() == 1)
451 if (frame.depth() == 16)
453 scalarType = IGTLinkImageMessage::TYPE_UINT16;
455 else if (frame.depth() == 8)
457 scalarType = IGTLinkImageMessage::TYPE_UINT8;
461 if (scalarType == -1)
463 std::cerr <<
"unknown image type" << std::endl;
469 imgMsg->SetDimensions(size);
470 imgMsg->SetSpacing(spacingF);
471 imgMsg->SetScalarType(scalarType);
472 imgMsg->SetSubVolume(svsize, svoffset);
473 imgMsg->AllocateScalars();
474 imgMsg->SetTimeStamp(timestamp);
476 unsigned char* destPtr =
reinterpret_cast<unsigned char*
> (imgMsg->GetScalarPointer());
477 uchar* src = frame.data;
479 int N = size[0] * size[1];
482 if (frame.channels() >= 3)
484 if (frame.isContinuous())
487 for (
int i = 0; i < N; ++i)
499 for (
int i=0; i<size[1]; ++i)
502 for (
int j=0; j<size[0]; ++j)
512 colorFormat =
"ARGB";
514 if (frame.channels() == 1)
516 if (!frame.isContinuous())
518 std::cout <<
"Error: Non-continous frame data." << std::endl;
523 for (
int i = 0; i < N; ++i)
530 imgMsg->SetDeviceName(
cstring_cast(QString(
"cxOpenCV [%1]").arg(colorFormat)));
534 igtl::Matrix4x4 matrix;
535 GetRandomTestMatrix(matrix);
536 imgMsg->SetMatrix(matrix);
static BoolPropertyPtr initialize(const QString &uid, QString name, QString help, bool value, QDomNode root=QDomNode())
DoublePropertyBasePtr getVideoPortOption(QDomElement root)
void setSendInterval(int milliseconds)
how often an image should be sent (in milliseconds)
virtual void initialize(StringMap arguments)
Utility class for describing a bounded numeric range.
virtual QStringList getArgumentDescription()
virtual void stopStreaming()
cstring_cast_Placeholder cstring_cast(const T &val)
QStringList getArgumentDescription()
BoolPropertyBasePtr getPrintPropertiesOption(QDomElement root)
virtual ~ImageStreamerOpenCV()
StringMap convertToCommandLineArguments(QDomElement root)
std::map< QString, QString > StringMap
virtual bool startStreaming(SenderPtr sender)
virtual QString getType()
boost::shared_ptr< class BoolPropertyBase > BoolPropertyBasePtr
igtl::SmartPointer< Self > Pointer
boost::shared_ptr< class DoublePropertyBase > DoublePropertyBasePtr
boost::shared_ptr< class DoubleProperty > DoublePropertyPtr
boost::shared_ptr< struct Package > PackagePtr
static DoublePropertyPtr initialize(const QString &uid, QString name, QString help, double value, DoubleRange range, int decimals, QDomNode root=QDomNode())
int convertStringWithDefault(QString text, int def)
boost::shared_ptr< class BoolProperty > BoolPropertyPtr
boost::shared_ptr< Sender > SenderPtr
virtual void initialize(StringMap arguments)
int getSendInterval() const
how often an image should be sent (in milliseconds)
virtual std::vector< PropertyPtr > getSettings(QDomElement root)