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"
56 #include "cxVideoServerConfig.h"
59 #include <opencv2/highgui/highgui.hpp>
60 #include <opencv2/imgproc/imgproc.hpp>
68 std::vector<PropertyPtr> retval;
79 retval->setGroup(
"OpenCV");
86 bool defaultValue =
false;
88 "When starting OpenCV, print properties to console",
90 retval->setAdvanced(
true);
91 retval->setGroup(
"OpenCV");
98 retval[
"--type"] =
"OpenCV";
99 retval[
"--videoport"] = this->
getVideoPortOption(root)->getValueAsVariant().toString();
101 retval[
"--properties"] =
"1";
109 retval <<
"--videoport: video id, default=0";
110 retval <<
"--in_width: width of incoming image, default=camera";
111 retval <<
"--in_height: height of incoming image, default=camera";
112 retval <<
"--out_width: width of outgoing image, default=camera";
113 retval <<
"--out_height: width of outgoing image, default=camera";
114 retval <<
"--properties: dump image properties";
130 void GetRandomTestMatrix(igtl::Matrix4x4& matrix)
160 mAvailableImage =
false;
164 mVideoCapture.reset(
new cv::VideoCapture());
167 connect(
mSendTimer, SIGNAL(timeout()),
this, SLOT(send()));
172 this->deinitialize_local();
191 void ImageStreamerOpenCV::deinitialize_local()
195 qApp->processEvents();
196 mVideoCapture->release();
197 mVideoCapture.reset(
new cv::VideoCapture());
201 void ImageStreamerOpenCV::initialize_local()
216 QString videoSource =
mArguments[
"videoport"];
219 bool sourceIsInt =
false;
220 videoSource.toInt(&sourceIsInt);
224 mVideoCapture->open(videoport);
228 mVideoCapture->open(videoSource.toStdString().c_str());
231 if (!mVideoCapture->isOpened())
233 cerr <<
"ImageStreamerOpenCV: Failed to open a video device or video file!\n" << endl;
241 mVideoCapture->grab();
243 catch(cv::Exception e)
245 CX_LOG_ERROR() <<
"OpenCV failed with message: " << e.what();
246 mVideoCapture->release();
253 int default_width = mVideoCapture->get(CV_CAP_PROP_FRAME_WIDTH);
254 int default_height = mVideoCapture->get(CV_CAP_PROP_FRAME_HEIGHT);
259 mVideoCapture->set(CV_CAP_PROP_FRAME_WIDTH, in_width);
260 mVideoCapture->set(CV_CAP_PROP_FRAME_HEIGHT, in_height);
265 mRescaleSize.setWidth(out_width);
266 mRescaleSize.setHeight(out_height);
269 this->dumpProperties();
271 std::cout <<
"ImageStreamerOpenCV: Started streaming from openCV device "
272 << videoSource.toStdString()
273 <<
", size=(" << in_width <<
"," << in_height <<
")";
274 if (( in_width!=mRescaleSize.width() )|| (in_height!=mRescaleSize.height()))
275 std::cout <<
". Scaled to (" << mRescaleSize.width() <<
"," << mRescaleSize.height() <<
")";
277 std::cout << std::endl;
285 this->initialize_local();
287 if (!
mSendTimer || !mVideoCapture->isOpened())
289 reportError(
"ImageStreamerOpenCV: Failed to start streaming: Not initialized.");
295 this->continousGrabEvent();
298 reportWarning(
"ImageStreamerOpenCV: Failed to start streaming: CX_USE_OpenCV not defined.");
299 #endif //CX_USE_OpenCV
309 this->deinitialize_local();
314 return (
mSendTimer && mVideoCapture->isOpened());
317 void ImageStreamerOpenCV::dumpProperties()
320 this->dumpProperty(CV_CAP_PROP_POS_MSEC,
"CV_CAP_PROP_POS_MSEC");
321 this->dumpProperty(CV_CAP_PROP_POS_FRAMES,
"CV_CAP_PROP_POS_FRAMES");
322 this->dumpProperty(CV_CAP_PROP_POS_AVI_RATIO,
"CV_CAP_PROP_POS_AVI_RATIO");
323 this->dumpProperty(CV_CAP_PROP_FRAME_WIDTH,
"CV_CAP_PROP_FRAME_WIDTH");
324 this->dumpProperty(CV_CAP_PROP_FRAME_HEIGHT,
"CV_CAP_PROP_FRAME_HEIGHT");
325 this->dumpProperty(CV_CAP_PROP_FPS,
"CV_CAP_PROP_FPS");
326 this->dumpProperty(CV_CAP_PROP_FOURCC,
"CV_CAP_PROP_FOURCC");
327 this->dumpProperty(CV_CAP_PROP_FRAME_COUNT,
"CV_CAP_PROP_FRAME_COUNT");
328 this->dumpProperty(CV_CAP_PROP_FORMAT,
"CV_CAP_PROP_FORMAT");
329 this->dumpProperty(CV_CAP_PROP_MODE,
"CV_CAP_PROP_MODE");
330 this->dumpProperty(CV_CAP_PROP_BRIGHTNESS,
"CV_CAP_PROP_BRIGHTNESS");
331 this->dumpProperty(CV_CAP_PROP_CONTRAST,
"CV_CAP_PROP_CONTRAST");
332 this->dumpProperty(CV_CAP_PROP_SATURATION,
"CV_CAP_PROP_SATURATION");
333 this->dumpProperty(CV_CAP_PROP_HUE,
"CV_CAP_PROP_HUE");
334 this->dumpProperty(CV_CAP_PROP_GAIN,
"CV_CAP_PROP_GAIN");
335 this->dumpProperty(CV_CAP_PROP_EXPOSURE,
"CV_CAP_PROP_EXPOSURE");
336 this->dumpProperty(CV_CAP_PROP_CONVERT_RGB,
"CV_CAP_PROP_CONVERT_RGB");
338 this->dumpProperty(CV_CAP_PROP_RECTIFICATION,
"CV_CAP_PROP_RECTIFICATION");
342 void ImageStreamerOpenCV::dumpProperty(
int val, QString name)
345 double value = mVideoCapture->get(val);
347 std::cout <<
"Property " << name.toStdString() <<
" : " << mVideoCapture->get(val) << std::endl;
356 void ImageStreamerOpenCV::continousGrabEvent()
361 QMetaObject::invokeMethod(
this,
"continousGrabEvent", Qt::QueuedConnection);
364 void ImageStreamerOpenCV::grab()
367 if (!mVideoCapture->isOpened())
373 mVideoCapture->grab();
374 mLastGrabTime = QDateTime::currentDateTime();
375 mAvailableImage =
true;
380 void ImageStreamerOpenCV::send()
384 if (!mAvailableImage)
390 package->mIgtLinkImageMessage = this->getImageMessage();
392 mAvailableImage =
false;
404 if (!mVideoCapture->isOpened())
407 QTime start = QTime::currentTime();
409 cv::Mat frame_source;
411 if (!mVideoCapture->retrieve(frame_source, 0))
414 if (this->thread() == QCoreApplication::instance()->thread() && !
mSender)
416 cv::imshow(
"ImageStreamerOpenCV", frame_source);
422 igtl::TimeStamp::Pointer timestamp;
423 timestamp = igtl::TimeStamp::New();
425 double grabTime = 1.0 / 1000 * (double) mLastGrabTime.toMSecsSinceEpoch();
426 timestamp->SetTime(grabTime);
427 static QDateTime lastlastGrabTime = mLastGrabTime;
430 lastlastGrabTime = mLastGrabTime;
432 cv::Mat frame = frame_source;
433 if (( frame.cols!=mRescaleSize.width() )|| (frame.rows!=mRescaleSize.height()))
435 cv::resize(frame_source, frame, cv::Size(mRescaleSize.width(), mRescaleSize.height()), 0, 0, CV_INTER_LINEAR);
444 size[0] = frame.cols;
445 size[1] = frame.rows;
454 if (frame.channels() == 3 || frame.channels() == 4)
456 scalarType = IGTLinkImageMessage::TYPE_UINT32;
458 else if (frame.channels() == 1)
460 if (frame.depth() == 16)
462 scalarType = IGTLinkImageMessage::TYPE_UINT16;
464 else if (frame.depth() == 8)
466 scalarType = IGTLinkImageMessage::TYPE_UINT8;
470 if (scalarType == -1)
472 std::cerr <<
"unknown image type" << std::endl;
478 imgMsg->SetDimensions(size);
479 imgMsg->SetSpacing(spacingF);
480 imgMsg->SetScalarType(scalarType);
481 imgMsg->SetSubVolume(svsize, svoffset);
482 imgMsg->AllocateScalars();
483 imgMsg->SetTimeStamp(timestamp);
485 unsigned char* destPtr =
reinterpret_cast<unsigned char*
> (imgMsg->GetScalarPointer());
486 uchar* src = frame.data;
488 int N = size[0] * size[1];
491 if (frame.channels() >= 3)
493 if (frame.isContinuous())
496 for (
int i = 0; i < N; ++i)
508 for (
int i=0; i<size[1]; ++i)
511 for (
int j=0; j<size[0]; ++j)
521 colorFormat =
"ARGB";
523 if (frame.channels() == 1)
525 if (!frame.isContinuous())
527 std::cout <<
"Error: Non-continous frame data." << std::endl;
532 for (
int i = 0; i < N; ++i)
539 imgMsg->SetDeviceName(
cstring_cast(QString(
"cxOpenCV [%1]").arg(colorFormat)));
543 igtl::Matrix4x4 matrix;
544 GetRandomTestMatrix(matrix);
545 imgMsg->SetMatrix(matrix);
static BoolPropertyPtr initialize(const QString &uid, QString name, QString help, bool value, QDomNode root=QDomNode())
void reportError(QString msg)
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
void reportWarning(QString msg)
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())
virtual void startStreaming(SenderPtr sender)
virtual bool isStreaming()
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)