7 #include "PlusConfigure.h" 8 #include "igsioTrackedFrame.h" 9 #include "vtkObjectFactory.h" 13 #include "vtkIGSIOTrackedFrameList.h" 14 #include "vtkIGSIOTransformRepository.h" 17 #include "vtksys/SystemTools.hxx" 28 , m_LastAlreadyRecordedFrameTimestamp(UNDEFINED_TIMESTAMP)
29 , m_NextFrameToBeRecordedTimestamp(0.0)
30 , m_SamplingFrameRate(8)
31 , RequestedFrameRate(0.0)
33 , m_LastUpdateTime(0.0)
34 , TotalFramesRecorded(0)
35 , EnableReconstruction(false)
36 , VolumeReconstructorAccessMutex(vtkSmartPointer<vtkIGSIORecursiveCriticalSection>::New())
76 deviceElement->SetAttribute(
"EnableReconstruction", this->
EnableReconstruction ?
"TRUE" :
"FALSE");
78 deviceElement->SetAttribute(
"OutputVolFilename", this->
OutputVolFilename.c_str());
90 bool lowestRateKnown =
false;
91 double lowestRate = 30;
98 lowestRateKnown =
true;
107 LOG_WARNING(
"vtkPlusVirtualVolumeReconstructor acquisition rate is not known");
139 double startTimeSec = vtkIGSIOAccurateTimer::GetSystemTime();
152 double requestedFramePeriodSec = 0.1;
154 if (requestedFrameRate <= 0)
159 if (requestedFrameRate > 0)
161 requestedFramePeriodSec = 1.0 / requestedFrameRate;
165 LOG_WARNING(
"RequestedFrameRate is invalid, use default: " << 1 / requestedFramePeriodSec);
177 LOG_ERROR(
"No output channels defined");
182 vtkSmartPointer<vtkIGSIOTrackedFrameList> recordedFrames = vtkSmartPointer<vtkIGSIOTrackedFrameList>::New();
185 LOG_ERROR(
"Error while getting tracked frame list from data collector during volume reconstruction. Last recorded timestamp: " << std::fixed <<
m_NextFrameToBeRecordedTimestamp);
187 int nbFramesRecorded = recordedFrames->GetNumberOfTrackedFrames();
191 LOG_ERROR(this->
GetDeviceId() <<
": Unable to add " << nbFramesRecorded <<
" frames for volume reconstruction");
198 double recordingTimeSec = vtkIGSIOAccurateTimer::GetSystemTime() - startTimeSec;
201 LOG_WARNING(
"Volume reconstruction of the acquired " << nbFramesRecorded <<
" frames takes too long time (" << recordingTimeSec <<
"sec instead of the allocated " <<
GetSamplingPeriodSec() <<
"sec). This can cause slow-down of the application and non-uniform sampling. Reduce the image acquisition rate, output size, or image clip rectangle size to resolve the problem.");
207 LOG_ERROR(
"Volume reconstruction cannot keep up with the acquisition. Skip " << recordingLagSec <<
" seconds of the data stream to catch up.");
222 LOG_WARNING(
"vtkPlusVirtualCapture is expecting no output channel(s) and there are " << this->
OutputChannels.size() <<
" channels. Output channel information will be dropped.");
228 LOG_ERROR(
"No input channel sent to vtkPlusVirtualCapture. Unable to save anything.");
236 inputChannel->Register(
this);
282 return this->
InputChannels[0]->GetOwnerDevice()->GetAcquisitionRate();
302 errorMessage.clear();
305 if (inputSeqFilename.empty())
307 errorMessage =
"Volume reconstruction failed, InputSeqFilename has not been defined";
308 LOG_INFO(errorMessage);
311 vtkSmartPointer<vtkIGSIOTrackedFrameList> trackedFrameList = vtkSmartPointer<vtkIGSIOTrackedFrameList>::New();
315 errorMessage =
"Volume reconstruction failed, unable to open input file specified in InputSeqFilename: " + inputImageSeqFileFullPath;
316 LOG_INFO(errorMessage);
326 errorMessage =
"vtkPlusReconstructVolumeCommand::Execute: failed, could not set up output volume - " +
errorDetail;
327 LOG_INFO(errorMessage);
333 errorMessage =
"vtkPlusReconstructVolumeCommand::Execute: failed, add frames failed";
334 LOG_INFO(errorMessage);
340 LOG_INFO(errorMessage);
349 outErrorMessage.clear();
352 if (!applyHoleFilling)
357 if (!applyHoleFilling)
364 outErrorMessage =
"Extracting gray levels failed";
365 LOG_ERROR(outErrorMessage);
377 const int numberOfFrames = trackedFrameList->GetNumberOfTrackedFrames();
378 int numberOfFramesAddedToVolume = 0;
379 for (
int frameIndex = 0; frameIndex < numberOfFrames; frameIndex += this->
VolumeReconstructor->GetSkipInterval())
381 LOG_TRACE(
"Adding frame to volume reconstructor: " << frameIndex);
382 igsioTrackedFrame* frame = trackedFrameList->GetTrackedFrame(frameIndex);
385 LOG_ERROR(
"Failed to update transform repository with frame #" << frameIndex);
390 bool insertedIntoVolume =
false;
391 bool isFirst = frameIndex == 0;
395 LOG_ERROR(
"Failed to add tracked frame to volume with frame #" << frameIndex);
399 if (insertedIntoVolume)
401 numberOfFramesAddedToVolume++;
404 trackedFrameList->Clear();
406 LOG_DEBUG(
"Number of frames added to the volume: " << numberOfFramesAddedToVolume <<
" out of " << numberOfFrames);
414 double samplingPeriodSec = 0.1;
421 LOG_WARNING(
"m_SamplingFrameRate value is invalid " <<
m_SamplingFrameRate <<
". Use default sampling period of " << samplingPeriodSec <<
" sec");
423 return samplingPeriodSec;
429 if (sharedTransformRepository == NULL)
431 LOG_ERROR(
"vtkPlusVirtualVolumeReconstructor::UpdateTransformRepository: shared transform repository is invalid");
vtkSmartPointer< vtkPlusVolumeReconstructor > VolumeReconstructor
virtual PlusStatus NotifyConfigured()
static const int VIRTUAL_DEVICE_FRAME_RATE
const char char * errorDetail
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
void SetOutputExtent(int *extent)
std::string GetOutputPath(const std::string &subPath)
Abstract interface for tracker and video devices.
vtkPlusVirtualVolumeReconstructor()
bool EnableReconstruction
PlusStatus AddFrames(vtkIGSIOTrackedFrameList *trackedFrameList)
virtual PlusStatus Reset()
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_WRITING(deviceConfig, rootConfigElement)
double GetSamplingPeriodSec()
ChannelContainer InputChannels
virtual std::string GetDeviceId() const
double m_NextFrameToBeRecordedTimestamp
long int TotalFramesRecorded
virtual ~vtkPlusVirtualVolumeReconstructor()
static vtkPlusConfig * GetInstance()
void SetOutputSpacing(double *spacing)
virtual double GetAcquisitionRate() const
virtual PlusStatus GetReconstructedVolumeFromFile(const std::string &inputSeqFilename, vtkImageData *reconstructedVolume, std::string &errorMessage)
virtual PlusStatus InternalDisconnect()
virtual int OutputChannelCount() const
double m_LastAlreadyRecordedFrameTimestamp
virtual PlusStatus InternalUpdate()
std::string OutputVolDeviceName
vtkStandardNewMacro(vtkPlusVirtualVolumeReconstructor)
static const int MAX_ALLOWED_RECONSTRUCTION_LAG_SEC
ChannelContainer::const_iterator ChannelContainerConstIterator
std::string OutputVolFilename
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *)
static igsioStatus Read(const std::string &filename, vtkIGSIOTrackedFrameList *frameList)
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_READING(deviceConfig, rootConfigElement)
const int m_SamplingFrameRate
virtual double GetAcquisitionRate() const
virtual PlusStatus GetTrackedFrameListSampled(double &aTimestampOfLastFrameAlreadyGot, double &aTimestampOfNextFrameToBeAdded, vtkIGSIOTrackedFrameList *aTrackedFrameList, double aSamplingPeriodSec, double maxTimeLimitSec=-1)
double RequestedFrameRate
bool StartThreadForInternalUpdates
void PrintSelf(ostream &os, vtkIndent indent)
vtkSmartPointer< vtkIGSIORecursiveCriticalSection > VolumeReconstructorAccessMutex
Contains an optional timestamped circular buffer containing the video images and a number of timestam...
PlusStatus GetReconstructedVolume(vtkImageData *reconstructedVolume, std::string &outErrorMessage, bool applyHoleFilling=true)
ChannelContainer OutputChannels
void SetOutputOrigin(double *origin)
void SetEnableReconstruction(bool aValue)
virtual void InternalWriteOutputChannels(vtkXMLDataElement *rootXMLElement)
vtkSmartPointer< vtkIGSIOTransformRepository > TransformRepository
virtual PlusStatus InternalConnect()
vtkPlusDevice * GetOwnerDevice() const
PlusStatus UpdateTransformRepository(vtkIGSIOTransformRepository *sharedTransformRepository)
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *)