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)
158 mAvailableImage =
false;
162 mVideoCapture.reset(
new cv::VideoCapture());
165 connect(
mSendTimer, SIGNAL(timeout()),
this, SLOT(send()));
170 this->deinitialize_local();
189 void ImageStreamerOpenCV::deinitialize_local()
193 qApp->processEvents();
194 mVideoCapture->release();
195 mVideoCapture.reset(
new cv::VideoCapture());
199 void ImageStreamerOpenCV::initialize_local()
213 QString videoSource =
mArguments[
"videoport"];
216 bool sourceIsInt =
false;
217 videoSource.toInt(&sourceIsInt);
222 mVideoCapture->open(videoport);
226 mVideoCapture->open(videoSource.toStdString().c_str());
229 if (!mVideoCapture->isOpened())
231 cerr <<
"ImageStreamerOpenCV: Failed to open a video device or video file!\n" << endl;
237 int default_width = mVideoCapture->get(CV_CAP_PROP_FRAME_WIDTH);
238 int default_height = mVideoCapture->get(CV_CAP_PROP_FRAME_HEIGHT);
243 mVideoCapture->set(CV_CAP_PROP_FRAME_WIDTH, in_width);
244 mVideoCapture->set(CV_CAP_PROP_FRAME_HEIGHT, in_height);
249 mRescaleSize.setWidth(out_width);
250 mRescaleSize.setHeight(out_height);
253 this->dumpProperties();
255 std::cout <<
"ImageStreamerOpenCV: Started streaming from openCV device "
256 << videoSource.toStdString()
257 <<
", size=(" << in_width <<
"," << in_height <<
")";
258 if (( in_width!=mRescaleSize.width() )|| (in_height!=mRescaleSize.height()))
259 std::cout <<
". Scaled to (" << mRescaleSize.width() <<
"," << mRescaleSize.height() <<
")";
261 std::cout << std::endl;
268 this->initialize_local();
272 std::cout <<
"ImageStreamerOpenCV: Failed to start streaming: Not initialized." << std::endl;
278 this->continousGrabEvent();
290 this->deinitialize_local();
293 void ImageStreamerOpenCV::dumpProperties()
296 this->dumpProperty(CV_CAP_PROP_POS_MSEC,
"CV_CAP_PROP_POS_MSEC");
297 this->dumpProperty(CV_CAP_PROP_POS_FRAMES,
"CV_CAP_PROP_POS_FRAMES");
298 this->dumpProperty(CV_CAP_PROP_POS_AVI_RATIO,
"CV_CAP_PROP_POS_AVI_RATIO");
299 this->dumpProperty(CV_CAP_PROP_FRAME_WIDTH,
"CV_CAP_PROP_FRAME_WIDTH");
300 this->dumpProperty(CV_CAP_PROP_FRAME_HEIGHT,
"CV_CAP_PROP_FRAME_HEIGHT");
301 this->dumpProperty(CV_CAP_PROP_FPS,
"CV_CAP_PROP_FPS");
302 this->dumpProperty(CV_CAP_PROP_FOURCC,
"CV_CAP_PROP_FOURCC");
303 this->dumpProperty(CV_CAP_PROP_FRAME_COUNT,
"CV_CAP_PROP_FRAME_COUNT");
304 this->dumpProperty(CV_CAP_PROP_FORMAT,
"CV_CAP_PROP_FORMAT");
305 this->dumpProperty(CV_CAP_PROP_MODE,
"CV_CAP_PROP_MODE");
306 this->dumpProperty(CV_CAP_PROP_BRIGHTNESS,
"CV_CAP_PROP_BRIGHTNESS");
307 this->dumpProperty(CV_CAP_PROP_CONTRAST,
"CV_CAP_PROP_CONTRAST");
308 this->dumpProperty(CV_CAP_PROP_SATURATION,
"CV_CAP_PROP_SATURATION");
309 this->dumpProperty(CV_CAP_PROP_HUE,
"CV_CAP_PROP_HUE");
310 this->dumpProperty(CV_CAP_PROP_GAIN,
"CV_CAP_PROP_GAIN");
311 this->dumpProperty(CV_CAP_PROP_EXPOSURE,
"CV_CAP_PROP_EXPOSURE");
312 this->dumpProperty(CV_CAP_PROP_CONVERT_RGB,
"CV_CAP_PROP_CONVERT_RGB");
314 this->dumpProperty(CV_CAP_PROP_RECTIFICATION,
"CV_CAP_PROP_RECTIFICATION");
318 void ImageStreamerOpenCV::dumpProperty(
int val, QString name)
321 double value = mVideoCapture->get(val);
323 std::cout <<
"Property " << name.toStdString() <<
" : " << mVideoCapture->get(val) << std::endl;
332 void ImageStreamerOpenCV::continousGrabEvent()
337 QMetaObject::invokeMethod(
this,
"continousGrabEvent", Qt::QueuedConnection);
340 void ImageStreamerOpenCV::grab()
343 if (!mVideoCapture->isOpened())
349 mVideoCapture->grab();
350 mLastGrabTime = QDateTime::currentDateTime();
351 mAvailableImage =
true;
356 void ImageStreamerOpenCV::send()
360 if (!mAvailableImage)
366 package->mIgtLinkImageMessage = this->getImageMessage();
368 mAvailableImage =
false;
380 if (!mVideoCapture->isOpened())
383 QTime start = QTime::currentTime();
385 cv::Mat frame_source;
387 if (!mVideoCapture->retrieve(frame_source, 0))
390 if (this->thread() == QCoreApplication::instance()->thread() && !
mSender)
392 cv::imshow(
"ImageStreamerOpenCV", frame_source);
398 igtl::TimeStamp::Pointer timestamp;
399 timestamp = igtl::TimeStamp::New();
401 double grabTime = 1.0 / 1000 * (double) mLastGrabTime.toMSecsSinceEpoch();
402 timestamp->SetTime(grabTime);
403 static QDateTime lastlastGrabTime = mLastGrabTime;
406 lastlastGrabTime = mLastGrabTime;
408 cv::Mat frame = frame_source;
409 if (( frame.cols!=mRescaleSize.width() )|| (frame.rows!=mRescaleSize.height()))
411 cv::resize(frame_source, frame, cv::Size(mRescaleSize.width(), mRescaleSize.height()), 0, 0, CV_INTER_LINEAR);
420 size[0] = frame.cols;
421 size[1] = frame.rows;
430 if (frame.channels() == 3 || frame.channels() == 4)
432 scalarType = IGTLinkImageMessage::TYPE_UINT32;
434 else if (frame.channels() == 1)
436 if (frame.depth() == 16)
438 scalarType = IGTLinkImageMessage::TYPE_UINT16;
440 else if (frame.depth() == 8)
442 scalarType = IGTLinkImageMessage::TYPE_UINT8;
446 if (scalarType == -1)
448 std::cerr <<
"unknown image type" << std::endl;
454 imgMsg->SetDimensions(size);
455 imgMsg->SetSpacing(spacingF);
456 imgMsg->SetScalarType(scalarType);
457 imgMsg->SetSubVolume(svsize, svoffset);
458 imgMsg->AllocateScalars();
459 imgMsg->SetTimeStamp(timestamp);
461 unsigned char* destPtr =
reinterpret_cast<unsigned char*
> (imgMsg->GetScalarPointer());
462 uchar* src = frame.data;
464 int N = size[0] * size[1];
467 if (frame.channels() >= 3)
469 if (frame.isContinuous())
472 for (
int i = 0; i < N; ++i)
484 for (
int i=0; i<size[1]; ++i)
487 for (
int j=0; j<size[0]; ++j)
497 colorFormat =
"ARGB";
499 if (frame.channels() == 1)
501 if (!frame.isContinuous())
503 std::cout <<
"Error: Non-continous frame data." << std::endl;
508 for (
int i = 0; i < N; ++i)
515 imgMsg->SetDeviceName(
cstring_cast(QString(
"cxOpenCV [%1]").arg(colorFormat)));
519 igtl::Matrix4x4 matrix;
520 GetRandomTestMatrix(matrix);
521 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)