14 #include <QCoreApplication> 17 #include <QHostAddress> 18 #include "vtkImageData.h" 19 #include "vtkSmartPointer.h" 20 #include "vtkMetaImageReader.h" 21 #include "vtkImageImport.h" 22 #include "vtkLookupTable.h" 23 #include "vtkImageMapToColors.h" 24 #include "vtkMetaImageWriter.h" 32 #include "cxVideoServerConfig.h" 35 #include <opencv2/highgui/highgui.hpp> 36 #include <opencv2/imgproc/imgproc.hpp> 44 std::vector<PropertyPtr> retval;
55 retval->setGroup(
"OpenCV");
62 bool defaultValue =
false;
64 "When starting OpenCV, print properties to console",
66 retval->setAdvanced(
true);
67 retval->setGroup(
"OpenCV");
74 retval[
"--type"] =
"OpenCV";
75 retval[
"--videoport"] = this->
getVideoPortOption(root)->getValueAsVariant().toString();
77 retval[
"--properties"] =
"1";
85 retval <<
"--videoport: video id, default=0";
86 retval <<
"--in_width: width of incoming image, default=camera";
87 retval <<
"--in_height: height of incoming image, default=camera";
88 retval <<
"--out_width: width of outgoing image, default=camera";
89 retval <<
"--out_height: width of outgoing image, default=camera";
90 retval <<
"--properties: dump image properties";
106 void GetRandomTestMatrix(igtl::Matrix4x4& matrix)
136 mAvailableImage =
false;
140 mVideoCapture.reset(
new cv::VideoCapture());
142 mSendTimer =
new QTimer(
this);
143 connect(mSendTimer, SIGNAL(timeout()),
this, SLOT(send()));
148 this->deinitialize_local();
167 void ImageStreamerOpenCV::deinitialize_local()
171 qApp->processEvents();
172 mVideoCapture->release();
173 mVideoCapture.reset(
new cv::VideoCapture());
177 void ImageStreamerOpenCV::initialize_local()
181 if (!mArguments.count(
"videoport"))
182 mArguments[
"videoport"] =
"0";
183 if (!mArguments.count(
"out_width"))
184 mArguments[
"out_width"] =
"";
185 if (!mArguments.count(
"out_height"))
186 mArguments[
"out_height"] =
"";
187 if (!mArguments.count(
"in_width"))
188 mArguments[
"in_width"] =
"";
189 if (!mArguments.count(
"in_height"))
190 mArguments[
"in_height"] =
"";
192 QString videoSource = mArguments[
"videoport"];
195 bool sourceIsInt =
false;
196 videoSource.toInt(&sourceIsInt);
200 mVideoCapture->open(videoport);
204 mVideoCapture->open(videoSource.toStdString().c_str());
207 if (!mVideoCapture->isOpened())
209 cerr <<
"ImageStreamerOpenCV: Failed to open a video device or video file!\n" << endl;
217 mVideoCapture->grab();
219 catch(cv::Exception& e)
221 CX_LOG_ERROR() <<
"OpenCV failed with message: " << e.what();
222 mVideoCapture->release();
229 int default_width = mVideoCapture->get(cv::CAP_PROP_FRAME_WIDTH);
230 int default_height = mVideoCapture->get(cv::CAP_PROP_FRAME_HEIGHT);
235 mVideoCapture->set(cv::CAP_PROP_FRAME_WIDTH, in_width);
236 mVideoCapture->set(cv::CAP_PROP_FRAME_HEIGHT, in_height);
241 mRescaleSize.setWidth(out_width);
242 mRescaleSize.setHeight(out_height);
244 if (mArguments.count(
"properties"))
245 this->dumpProperties();
247 std::cout <<
"ImageStreamerOpenCV: Started streaming from openCV device " 248 << videoSource.toStdString()
249 <<
", size=(" << in_width <<
"," << in_height <<
")";
250 if (( in_width!=mRescaleSize.width() )|| (in_height!=mRescaleSize.height()))
251 std::cout <<
". Scaled to (" << mRescaleSize.width() <<
"," << mRescaleSize.height() <<
")";
253 std::cout << std::endl;
261 this->initialize_local();
263 if (!mSendTimer || !mVideoCapture->isOpened())
265 reportError(
"ImageStreamerOpenCV: Failed to start streaming: Not initialized.");
270 mSendTimer->start(getSendInterval());
271 this->continousGrabEvent();
274 reportWarning(
"ImageStreamerOpenCV: Failed to start streaming: CX_USE_OpenCV not defined.");
275 #endif //CX_USE_OpenCV 285 this->deinitialize_local();
290 return (mSendTimer && mVideoCapture->isOpened());
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()
334 if (!mSendTimer->isActive())
337 QMetaObject::invokeMethod(
this,
"continousGrabEvent", Qt::QueuedConnection);
340 void ImageStreamerOpenCV::grab()
343 if (!mVideoCapture->isOpened())
350 bool success = mVideoCapture->grab();
352 mLastGrabTime = QDateTime::currentDateTime();
353 mAvailableImage = success;
358 void ImageStreamerOpenCV::send()
360 if (!mSender || !mSender->isReady())
362 if (!mAvailableImage)
368 package->mImage = this->getImageMessage();
369 mSender->send(package);
370 mAvailableImage =
false;
377 ImagePtr ImageStreamerOpenCV::getImageMessage()
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);
395 cv::Mat frame = frame_source;
396 if (( frame.cols!=mRescaleSize.width() )|| (frame.rows!=mRescaleSize.height()))
398 cv::resize(frame_source, frame, cv::Size(mRescaleSize.width(), mRescaleSize.height()), 0, 0, cv::INTER_LINEAR);
403 image->setAcquisitionTime(mLastGrabTime);
410 vtkImageDataPtr ImageStreamerOpenCV::convertTovtkImageData(cv::Mat& frame)
414 Eigen::Array3i dim(frame.cols, frame.rows, 1);
416 retval->SetDimensions(dim.data());
417 retval->SetSpacing(1,1,1);
422 if (frame.channels() == 3)
424 dataType = VTK_UNSIGNED_CHAR;
426 else if (frame.channels() == 1)
433 if (frame.depth() == 8)
435 dataType = VTK_UNSIGNED_CHAR;
441 std::cerr <<
"unknown image type" << std::endl;
445 retval->AllocateScalars(dataType, frame.channels());
457 unsigned char* dest =
reinterpret_cast<unsigned char*
> (retval->GetScalarPointer());
458 uchar* src = frame.data;
459 int N = frame.rows * frame.cols;
462 if (frame.channels() == 3)
464 if (frame.isContinuous())
467 for (
int i = 0; i < N; ++i)
479 for (
int i=0; i<dim[1]; ++i)
482 for (
int j=0; j<dim[0]; ++j)
494 if (frame.channels() == 1)
496 if (!frame.isContinuous())
498 std::cout <<
"Error: Non-continous frame data." << std::endl;
503 for (
int i = 0; i < N; ++i)
static BoolPropertyPtr initialize(const QString &uid, QString name, QString help, bool value, QDomNode root=QDomNode())
void reportError(QString msg)
DoublePropertyBasePtr getVideoPortOption(QDomElement root)
virtual void initialize(StringMap arguments)
Utility class for describing a bounded numeric range.
boost::shared_ptr< class Image > ImagePtr
virtual QStringList getArgumentDescription()
virtual void stopStreaming()
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
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)
virtual std::vector< PropertyPtr > getSettings(QDomElement root)
Namespace for all CustusX production code.