8 #include "PlusConfigure.h" 14 #include <vtkImageData.h> 15 #include <vtkObjectFactory.h> 18 #if CV_MAJOR_VERSION > 3 19 #include <opencv2/calib3d.hpp> 21 #include <opencv2/imgproc.hpp> 22 #include <opencv2/highgui.hpp> 32 , RequestedCaptureAPI(
cv::CAP_ANY)
36 , UndistortedFrame(nullptr)
37 , CameraMatrix(nullptr)
38 , DistortionCoefficients(nullptr)
39 , AutofocusEnabled(false)
40 , AutoexposureEnabled(false)
57 os << indent <<
"VideoURL: " << this->
VideoURL << std::endl;
58 os << indent <<
"DeviceIndex: " << this->
DeviceIndex << std::endl;
63 os << indent <<
"CamerMatrix: " << *this->
CameraMatrix << std::endl;
74 LOG_TRACE(
"vtkPlusOpenCVCaptureVideoSource::ReadConfiguration");
77 XML_READ_STRING_ATTRIBUTE_OPTIONAL(
VideoURL, deviceConfig);
78 std::string captureApi;
79 XML_READ_STRING_ATTRIBUTE_NONMEMBER_OPTIONAL(CaptureAPI, captureApi, deviceConfig);
80 if (!captureApi.empty())
85 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
int,
DeviceIndex, deviceConfig);
86 int frameSize[3] = { 0, 0, 1 };
87 XML_READ_VECTOR_ATTRIBUTE_NONMEMBER_OPTIONAL(
int, 2,
FrameSize, frameSize, deviceConfig);
88 if (deviceConfig->GetAttribute(
"FrameSize") != NULL)
90 std::copy(std::begin(frameSize), std::end(frameSize), this->
FrameSize.begin());
93 XML_READ_STRING_ATTRIBUTE_OPTIONAL(
FourCC, deviceConfig);
96 LOG_WARNING(
"Unable to parse desired FourCC string.");
100 std::vector<double> camMat;
102 XML_READ_STD_ARRAY_ATTRIBUTE_NONMEMBER_EXACT_OPTIONAL(
double,
CameraMatrix, 9, camMat, deviceConfig);
103 if (deviceConfig->GetAttribute(
"CameraMatrix") != NULL)
105 this->
CameraMatrix = std::make_shared<cv::Mat>(3, 3, CV_64F);
106 memcpy(this->
CameraMatrix->data, camMat.data(),
sizeof(double) * 9);
109 std::vector<double> distCoeffs(8, std::numeric_limits<double>::infinity());
110 XML_READ_STD_ARRAY_ATTRIBUTE_NONMEMBER_OPTIONAL(
double,
DistortionCoefficients, 8, distCoeffs, deviceConfig);
111 if (deviceConfig->GetAttribute(
"DistortionCoefficients") != NULL)
113 std::vector<double>::difference_type
count = std::count_if(distCoeffs.begin(), distCoeffs.end(), [
this](
const double & val) {
return val != std::numeric_limits<double>::infinity(); });
116 for (std::vector<double>::difference_type
i = 0;
i <
count; ++
i)
118 this->DistortionCoefficients->at<
double>(
i, 0) = distCoeffs[
i];
131 LOG_TRACE(
"vtkPlusOpenCVCaptureVideoSource::WriteConfiguration");
134 XML_WRITE_STRING_ATTRIBUTE_REMOVE_IF_EMPTY(
VideoURL, deviceConfig);
141 deviceConfig->SetIntAttribute(
"DeviceIndex", this->
DeviceIndex);
145 deviceConfig->SetVectorAttribute(
"CameraMatrix", 9, this->
CameraMatrix->ptr<
double>(0));
149 deviceConfig->SetVectorAttribute(
"DistortionCoefficients", this->
DistortionCoefficients->rows, this->DistortionCoefficients->ptr<
double>(0));
152 XML_WRITE_STRING_ATTRIBUTE_IF_NOT_EMPTY(
FourCC, deviceConfig);
187 LOG_ERROR(
"No device identification method defined. Please add either \"VideoURL\" or \"DeviceIndex\" attribute to configuration.");
191 if (!this->
Capture->isOpened())
193 LOG_ERROR(
"Unable to open OpenCV video device.");
199 if (!this->
Capture->set(cv::CAP_PROP_FPS, this->AcquisitionRate))
201 LOG_WARNING(
"Unable to set requested acquisition rate: " << this->
AcquisitionRate);
205 LOG_WARNING(
"Unable to set requested fourCC code: " << this->
FourCC);
209 if (!this->
Capture->set(cv::CAP_PROP_FRAME_HEIGHT, this->FrameSize[1]))
211 LOG_ERROR(
"Unable to set the requested height of the capture device.");
213 if (!this->
Capture->set(cv::CAP_PROP_FRAME_WIDTH, this->FrameSize[0]))
215 LOG_ERROR(
"Unable to set the requested width of the capture device.");
218 if (!this->
Capture->set(cv::CAP_PROP_AUTOFOCUS, this->AutofocusEnabled ? 1 : 0))
222 LOG_WARNING(
"Could not set the autofocus property.");
225 if (!this->
Capture->set(cv::CAP_PROP_AUTO_EXPOSURE, this->AutoexposureEnabled ? 1 : 0))
229 LOG_WARNING(
"Could not set the autoexposure property.");
235 this->
FrameSize[1] = cvRound(this->
Capture->get(cv::CAP_PROP_FRAME_HEIGHT));
238 this->
Frame = std::make_shared<cv::Mat>(this->FrameSize[1], this->FrameSize[0], CV_8UC3);
242 this->
UndistortedFrame = std::make_shared<cv::Mat>(this->FrameSize[1], this->FrameSize[0], CV_8UC3);
249 if (!this->
Capture->isOpened())
253 LOG_ERROR(
"Unable to open device at URL: " << this->
VideoURL);
257 LOG_ERROR(
"Unable to open device at device index: " << this->
DeviceIndex);
269 this->
Frame =
nullptr;
278 LOG_TRACE(
"vtkPlusOpenCVCaptureVideoSource::InternalUpdate");
280 if (!this->
Capture->isOpened())
287 if (!this->
Capture->read(*this->Frame))
289 LOG_ERROR(
"Unable to receive frame");
304 LOG_ERROR(
"Unable to grab a video source. Skipping frame.");
334 LOG_WARNING(
"vtkPlusOpenCVCaptureVideoSource is expecting one output channel and there are " << this->
OutputChannels.size() <<
" channels. First output channel will be used.");
339 LOG_ERROR(
"No output channels defined for vtkPlusOpenCVCaptureVideoSource. Cannot proceed.");
346 LOG_WARNING(
"Only one of CameraMatrix or DistortionCoefficients defined in config file, cannot perform undistortion.");
351 LOG_ERROR(
"No device identification method defined. Please add either \"VideoURL\" or \"DeviceIndex\" attribute to configuration.");
357 LOG_ERROR(
"Cannot index FFMPEG devices by DeviceIndex. VideoURL must be used instead.");
367 if (apiString.compare(
"CAP_ANY") == 0)
371 else if (apiString.compare(
"CAP_VFW") == 0)
375 else if (apiString.compare(
"CAP_V4L") == 0)
379 else if (apiString.compare(
"CAP_V4L2") == 0)
383 else if (apiString.compare(
"CAP_FIREWIRE") == 0)
385 return cv::CAP_FIREWIRE;
387 else if (apiString.compare(
"CAP_FIREWARE") == 0)
389 return cv::CAP_FIREWARE;
391 else if (apiString.compare(
"CAP_IEEE1394") == 0)
393 return cv::CAP_IEEE1394;
395 else if (apiString.compare(
"CAP_DC1394") == 0)
397 return cv::CAP_DC1394;
399 else if (apiString.compare(
"CAP_CMU1394") == 0)
401 return cv::CAP_CMU1394;
403 else if (apiString.compare(
"CAP_QT") == 0)
407 else if (apiString.compare(
"CAP_UNICAP") == 0)
409 return cv::CAP_UNICAP;
411 else if (apiString.compare(
"CAP_DSHOW") == 0)
413 return cv::CAP_DSHOW;
415 else if (apiString.compare(
"CAP_PVAPI") == 0)
417 return cv::CAP_PVAPI;
419 else if (apiString.compare(
"CAP_OPENNI") == 0)
421 return cv::CAP_OPENNI;
423 else if (apiString.compare(
"CAP_OPENNI_ASUS") == 0)
425 return cv::CAP_OPENNI_ASUS;
427 else if (apiString.compare(
"CAP_ANDROID") == 0)
429 return cv::CAP_ANDROID;
431 else if (apiString.compare(
"CAP_XIAPI") == 0)
433 return cv::CAP_XIAPI;
435 else if (apiString.compare(
"CAP_AVFOUNDATION") == 0)
437 return cv::CAP_AVFOUNDATION;
439 else if (apiString.compare(
"CAP_GIGANETIX") == 0)
441 return cv::CAP_GIGANETIX;
443 else if (apiString.compare(
"CAP_MSMF") == 0)
447 else if (apiString.compare(
"CAP_WINRT") == 0)
449 return cv::CAP_WINRT;
451 else if (apiString.compare(
"CAP_INTELPERC") == 0)
453 return cv::CAP_INTELPERC;
455 else if (apiString.compare(
"CAP_OPENNI2") == 0)
457 return cv::CAP_OPENNI2;
459 else if (apiString.compare(
"CAP_OPENNI2_ASUS") == 0)
461 return cv::CAP_OPENNI2_ASUS;
463 else if (apiString.compare(
"CAP_GPHOTO2") == 0)
465 return cv::CAP_GPHOTO2;
467 else if (apiString.compare(
"CAP_GSTREAMER") == 0)
469 return cv::CAP_GSTREAMER;
471 else if (apiString.compare(
"CAP_FFMPEG") == 0)
473 return cv::CAP_FFMPEG;
475 else if (apiString.compare(
"CAP_IMAGES") == 0)
477 return cv::CAP_IMAGES;
479 else if (apiString.compare(
"CAP_ARAVIS") == 0)
481 return cv::CAP_ARAVIS;
484 LOG_WARNING(
"Unable to match requested API " << apiString <<
". Defaulting to CAP_ANY");
488 #define _StringFromEnum(x) std::string(#x) 498 case cv::CAP_FIREWIRE:
510 case cv::CAP_OPENNI_ASUS:
512 case cv::CAP_ANDROID:
516 case cv::CAP_AVFOUNDATION:
518 case cv::CAP_GIGANETIX:
524 case cv::CAP_INTELPERC:
526 case cv::CAP_OPENNI2:
528 case cv::CAP_OPENNI2_ASUS:
530 case cv::CAP_GPHOTO2:
532 case cv::CAP_GSTREAMER:
544 #undef _StringFromEnum
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
virtual PlusStatus InternalDisconnect()
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_WRITING(deviceConfig, rootConfigElement)
std::shared_ptr< cv::VideoCapture > Capture
virtual PlusStatus InternalUpdate()
vtkStandardNewMacro(vtkPlusOpenCVCaptureVideoSource)
PlusStatus SetInputFrameSize(unsigned int x, unsigned int y, unsigned int z)
virtual PlusStatus AddItem(vtkImageData *frame, US_IMAGE_ORIENTATION usImageOrientation, US_IMAGE_TYPE imageType, long frameNumber, double unfilteredTimestamp=UNDEFINED_TIMESTAMP, double filteredTimestamp=UNDEFINED_TIMESTAMP, const igsioFieldMapType *customFields=NULL)
Class for interfacing an OpenCVC capture device and recording frames into a Plus buffer.
bool RequireImageOrientationInConfiguration
PlusStatus SetImageType(US_IMAGE_TYPE imageType)
std::shared_ptr< cv::Mat > UndistortedFrame
PlusStatus SetPixelType(igsioCommon::VTKScalarPixelType pixelType)
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *config)
virtual PlusStatus Disconnect()
std::shared_ptr< cv::Mat > DistortionCoefficients
PlusStatus GetFirstActiveOutputVideoSource(vtkPlusDataSource *&aVideoSource)
std::shared_ptr< cv::Mat > CameraMatrix
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
unsigned long FrameNumber
static std::string StringFromCaptureAPI(cv::VideoCaptureAPIs api)
vtkPlusOpenCVCaptureVideoSource()
virtual PlusStatus Connect()
~vtkPlusOpenCVCaptureVideoSource()
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_READING(deviceConfig, rootConfigElement)
cv::VideoCaptureAPIs RequestedCaptureAPI
virtual US_IMAGE_ORIENTATION GetInputImageOrientation()
Phidget_ChannelClass uint32_t * count
bool StartThreadForInternalUpdates
virtual PlusStatus InternalConnect()
ChannelContainer OutputChannels
PlusStatus SetNumberOfScalarComponents(unsigned int numberOfScalarComponents)
std::shared_ptr< cv::Mat > Frame
virtual PlusStatus NotifyConfigured()
PlusStatus FreezeDevice(bool freeze)
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *config)
static cv::VideoCaptureAPIs CaptureAPIFromString(const std::string &apiString)
#define _StringFromEnum(x)
virtual int GetNumberOfItems()
Interface to a 3D positioning tool, video source, or generalized data stream.