8 #include "PlusConfigure.h" 10 #include "igsioTrackedFrame.h" 14 #include "vtkIGSIOTrackedFrameList.h" 17 #include <vtkDoubleArray.h> 18 #include <vtkImageData.h> 19 #include <vtkIntArray.h> 21 #include <vtkMatrix4x4.h> 22 #include <vtkObjectFactory.h> 23 #include <vtkUnsignedLongLongArray.h> 26 #include <vtkStreamingVolumeCodec.h> 33 #define LOCAL_LOG_ERROR(msg) \ 35 std::ostringstream msgStream; \ 36 if( this->DescriptiveName == NULL ) \ 38 msgStream << " " << msg << std::ends; \ 42 msgStream << this->DescriptiveName << ": " << msg << std::ends; \ 44 std::string finalStr(msgStream.str()); \ 45 LOG_ERROR(finalStr); \ 47 #define LOCAL_LOG_WARNING(msg) \ 49 std::ostringstream msgStream; \ 50 if( this->DescriptiveName == NULL ) \ 52 msgStream << " " << msg << std::ends; \ 56 msgStream << this->DescriptiveName << ": " << msg << std::ends; \ 58 std::string finalStr(msgStream.str()); \ 59 LOG_WARNING(finalStr); \ 61 #define LOCAL_LOG_DEBUG(msg) \ 63 std::ostringstream msgStream; \ 64 if( this->DescriptiveName == NULL ) \ 66 msgStream << " " << msg << std::ends; \ 70 msgStream << this->DescriptiveName << ": " << msg << std::ends; \ 72 std::string finalStr(msgStream.str()); \ 73 LOG_DEBUG(finalStr); \ 80 : PixelType(VTK_UNSIGNED_CHAR)
81 , NumberOfScalarComponents(1)
82 , ImageType(US_IMG_BRIGHTNESS)
83 , ImageOrientation(US_IMG_ORIENT_MF)
85 , MaxAllowedTimeDifference(0.5)
86 , DescriptiveName(NULL)
113 this->Superclass::PrintSelf(os, indent);
115 os << indent <<
"Scalar pixel type: " << vtkImageScalarTypeNameMacro(this->
GetPixelType()) << std::endl;
116 os << indent <<
"Image type: " << igsioCommon::GetStringFromUsImageType(this->
GetImageType()) << std::endl;
117 os << indent <<
"Image orientation: " << igsioCommon::GetStringFromUsImageOrientation(this->
GetImageOrientation()) << std::endl;
119 os << indent <<
"StreamBuffer: " << this->
StreamBuffer <<
"\n";
120 if (this->StreamBuffer)
122 this->StreamBuffer->
PrintSelf(os, indent.GetNextIndent());
129 igsioLockGuard<StreamItemCircularBuffer> dataBufferGuardedLock(this->
StreamBuffer);
200 <<
"x" << this->
GetFrameSize()[1] <<
"x" << this->
GetFrameSize()[2] <<
" received: " << frameSizeInPx[0] <<
"x" << frameSizeInPx[1] <<
"x" << frameSizeInPx[2] <<
")!");
207 <<
") and buffer pixel type (" << vtkImageScalarTypeNameMacro(this->
GetPixelType()) <<
") mismatch");
213 LOCAL_LOG_WARNING(
"Frame image type (" << igsioCommon::GetStringFromUsImageType(imgType) <<
") and buffer image type (" << igsioCommon::GetStringFromUsImageType(this->
GetImageType()) <<
") mismatch");
228 US_IMAGE_ORIENTATION usImageOrientation,
229 US_IMAGE_TYPE imageType,
231 const std::array<int, 3>& clipRectangleOrigin,
232 const std::array<int, 3>& clipRectangleSize,
233 double unfilteredTimestamp,
234 double filteredTimestamp,
235 const igsioFieldMapType* customFields )
239 LOCAL_LOG_ERROR(
"vtkPlusBuffer: Unable to add NULL frame to video buffer!");
243 const int* frameExtent = frame->GetExtent();
244 if (frameExtent[1] - frameExtent[0] + 1 < 0 || frameExtent[3] - frameExtent[2] + 1 < 0 || frameExtent[5] - frameExtent[4] + 1 < 0)
246 LOG_ERROR(
"Invalid negative values sent to vtkPlusUsDevice::AddItem. Aborting.");
250 FrameSizeType frameSize = {static_cast<unsigned int>(frameExtent[1] - frameExtent[0] + 1), static_cast<unsigned int>(frameExtent[3] - frameExtent[2] + 1), static_cast<unsigned int>(frameExtent[5] - frameExtent[4] + 1)};
251 return this->
AddItem(reinterpret_cast<unsigned char*>(frame->GetScalarPointer()),
254 frame->GetScalarType(),
255 frame->GetNumberOfScalarComponents(),
269 const std::array<int, 3>& clipRectangleOrigin,
270 const std::array<int, 3>& clipRectangleSize,
271 double unfilteredTimestamp,
272 double filteredTimestamp,
273 const igsioFieldMapType* customFields )
277 LOCAL_LOG_ERROR(
"vtkPlusBuffer: Unable to add NULL frame to video buffer!");
281 if (frame->IsFrameEncoded())
283 unsigned int numberOfComponents = 0;
284 frame->GetNumberOfScalarComponents(numberOfComponents);
285 int dimensions[3] = { 0, 0, 0 };
286 frame->GetEncodedFrame()->GetDimensions(dimensions);
287 FrameSizeType frameSize = { static_cast<unsigned int>(dimensions[0]),
288 static_cast<unsigned int>(dimensions[1]),
289 static_cast<unsigned int>(dimensions[2])
292 frame->GetImageOrientation(),
296 frame->GetImageType(),
304 frame->GetEncodedFrame());
308 return this->
AddItem(frame->GetImage(),
309 frame->GetImageOrientation(),
310 frame->GetImageType(),
323 double unfilteredTimestamp,
324 double filteredTimestamp)
331 if (unfilteredTimestamp == UNDEFINED_TIMESTAMP)
333 unfilteredTimestamp = vtkIGSIOAccurateTimer::GetSystemTime();
335 if (filteredTimestamp == UNDEFINED_TIMESTAMP)
337 bool filteredTimestampProbablyValid =
true;
340 LOCAL_LOG_DEBUG(
"Failed to create filtered timestamp for tracker buffer item with item index: " << frameNumber);
343 if (!filteredTimestampProbablyValid)
345 LOG_INFO(
"Filtered timestamp is probably invalid for tracker buffer item with item index=" << frameNumber <<
", time=" << unfilteredTimestamp <<
". The item may have been tagged with an inaccurate timestamp, therefore it will not be recorded.");
357 igsioLockGuard<StreamItemCircularBuffer> dataBufferGuardedLock(this->
StreamBuffer);
361 LOCAL_LOG_DEBUG(
"vtkPlusBuffer: Failed to prepare for adding new frame to tracker buffer!");
367 if (newObjectInBuffer == NULL)
369 LOCAL_LOG_ERROR(
"vtkPlusBuffer: Failed to get pointer to data buffer object from the tracker buffer for the new frame!");
375 newObjectInBuffer->
SetIndex(frameNumber);
376 newObjectInBuffer->
SetUid(itemUid);
379 for (igsioFieldMapType::const_iterator it = fields.begin(); it != fields.end(); ++it)
381 newObjectInBuffer->
SetFrameField(it->first, it->second.second, it->second.first);
382 std::string name(it->first);
390 US_IMAGE_ORIENTATION usImageOrientation,
391 const FrameSizeType& inputFrameSizeInPx,
393 unsigned int numberOfScalarComponents,
394 US_IMAGE_TYPE imageType,
395 int numberOfBytesToSkip,
397 const std::array<int, 3>& clipRectangleOrigin,
398 const std::array<int, 3>& clipRectangleSize,
399 double unfilteredTimestamp ,
400 double filteredTimestamp ,
401 const igsioFieldMapType* customFields ,
402 vtkStreamingVolumeFrame* encodedFrame )
404 if (unfilteredTimestamp == UNDEFINED_TIMESTAMP)
406 unfilteredTimestamp = vtkIGSIOAccurateTimer::GetSystemTime();
409 if (filteredTimestamp == UNDEFINED_TIMESTAMP)
411 bool filteredTimestampProbablyValid =
true;
414 LOCAL_LOG_WARNING(
"Failed to create filtered timestamp for video buffer item with item index: " << frameNumber);
417 if (!filteredTimestampProbablyValid)
419 LOG_INFO(
"Filtered timestamp is probably invalid for video buffer item with item index=" << frameNumber <<
", time=" <<
420 unfilteredTimestamp <<
". The item may have been tagged with an inaccurate timestamp, therefore it will not be recorded.");
429 if (imageDataPtr == NULL && encodedFrame == NULL)
431 LOG_ERROR(
"vtkPlusBuffer: Unable to add NULL frame to video buffer!");
435 igsioVideoFrame::FlipInfoType flipInfo;
438 LOG_ERROR(
"Failed to convert image data to the requested orientation, from " << igsioCommon::GetStringFromUsImageOrientation(usImageOrientation) <<
439 " to " << igsioCommon::GetStringFromUsImageOrientation(this->
ImageOrientation));
444 FrameSizeType outputFrameSizeInPx = { inputFrameSizeInPx[0], inputFrameSizeInPx[1], inputFrameSizeInPx[2] };
445 if (igsioCommon::IsClippingRequested(clipRectangleOrigin, clipRectangleSize))
447 outputFrameSizeInPx[0] = clipRectangleSize[0];
448 outputFrameSizeInPx[1] = clipRectangleSize[1];
449 outputFrameSizeInPx[2] = clipRectangleSize[2];
452 if (flipInfo.tranpose == igsioVideoFrame::TRANSPOSE_IJKtoKIJ)
454 unsigned int temp = outputFrameSizeInPx[0];
455 outputFrameSizeInPx[0] = outputFrameSizeInPx[2];
456 outputFrameSizeInPx[2] = outputFrameSizeInPx[1];
457 outputFrameSizeInPx[1] = temp;
460 if (!this->
CheckFrameFormat(outputFrameSizeInPx, pixelType, imageType, numberOfScalarComponents))
462 LOG_ERROR(
"vtkPlusBuffer: Unable to add frame to video buffer - frame format doesn't match!");
468 igsioLockGuard<StreamItemCircularBuffer> dataBufferGuardedLock(this->
StreamBuffer);
472 LOCAL_LOG_DEBUG(
"vtkPlusBuffer: Failed to prepare for adding new frame to video buffer!");
478 if (newObjectInBuffer == NULL)
480 LOCAL_LOG_ERROR(
"vtkPlusBuffer: Failed to get pointer to video buffer object from the video buffer for the new frame!");
484 FrameSizeType receivedFrameSize = { 0, 0, 0 };
485 newObjectInBuffer->
GetFrame().GetFrameSize(receivedFrameSize);
487 if (imageDataPtr && !encodedFrame &&
488 (outputFrameSizeInPx[0] != receivedFrameSize[0]
489 || outputFrameSizeInPx[1] != receivedFrameSize[1]
490 || outputFrameSizeInPx[2] != receivedFrameSize[2]))
492 LOCAL_LOG_ERROR(
"Input frame size is different from buffer frame size (input: " <<
493 outputFrameSizeInPx[0] <<
"x" << outputFrameSizeInPx[1] <<
"x" << outputFrameSizeInPx[2] <<
495 receivedFrameSize[0] <<
"x" << receivedFrameSize[1] <<
"x" << receivedFrameSize[2] <<
")!");
500 if (imageDataPtr != NULL)
502 unsigned char* byteImageDataPtr = reinterpret_cast<unsigned char*>(imageDataPtr);
503 byteImageDataPtr += numberOfBytesToSkip;
505 if (igsioVideoFrame::GetOrientedClippedImage(byteImageDataPtr, flipInfo, imageType, pixelType, numberOfScalarComponents, inputFrameSizeInPx, newObjectInBuffer->
GetFrame(), clipRectangleOrigin, clipRectangleSize) !=
PLUS_SUCCESS)
507 LOCAL_LOG_ERROR(
"Failed to convert input US image to the requested orientation!");
511 else if (encodedFrame != NULL)
513 newObjectInBuffer->
GetFrame().SetEncodedFrame(encodedFrame);
518 newObjectInBuffer->
SetIndex(frameNumber);
519 newObjectInBuffer->
SetUid(itemUid);
520 newObjectInBuffer->
GetFrame().SetImageType(imageType);
523 if (customFields != NULL)
525 for (igsioFieldMapType::const_iterator it = customFields->begin(); it != customFields->end(); ++it)
527 newObjectInBuffer->
SetFrameField(it->first, it->second.second, it->second.first);
528 std::string name(it->first);
529 if (name.find(
"Transform") != std::string::npos)
540 PlusStatus vtkPlusBuffer::AddItem(
void* imageDataPtr,
const FrameSizeType& frameSize,
unsigned int inputFrameSizeInBytes, US_IMAGE_TYPE imageType,
long frameNumber,
double unfilteredTimestamp ,
double filteredTimestamp ,
const igsioFieldMapType* customFields )
542 if (unfilteredTimestamp == UNDEFINED_TIMESTAMP)
544 unfilteredTimestamp = vtkIGSIOAccurateTimer::GetSystemTime();
547 if (filteredTimestamp == UNDEFINED_TIMESTAMP)
549 bool filteredTimestampProbablyValid =
true;
552 LOCAL_LOG_WARNING(
"Failed to create filtered timestamp for video buffer item with item index: " << frameNumber);
555 if (!filteredTimestampProbablyValid)
557 LOG_INFO(
"Filtered timestamp is probably invalid for video buffer item with item index=" << frameNumber <<
", time=" <<
558 unfilteredTimestamp <<
". The item may have been tagged with an inaccurate timestamp, therefore it will not be recorded.");
567 if (imageDataPtr == NULL)
569 LOG_ERROR(
"vtkPlusBuffer: Unable to add NULL frame to video buffer!");
575 LOG_ERROR(
"vtkPlusBuffer: Unable to add frame to video buffer - frame format doesn't match!");
581 igsioLockGuard<StreamItemCircularBuffer> dataBufferGuardedLock(this->
StreamBuffer);
585 LOCAL_LOG_DEBUG(
"vtkPlusBuffer: Failed to prepare for adding new frame to video buffer!");
591 if (newObjectInBuffer == NULL)
593 LOCAL_LOG_ERROR(
"vtkPlusBuffer: Failed to get pointer to video buffer object from the video buffer for the new frame!");
597 unsigned int bufferFrameSizeBytes = newObjectInBuffer->
GetFrame().GetFrameSizeInBytes();
598 if (bufferFrameSizeBytes < inputFrameSizeInBytes)
600 LOCAL_LOG_ERROR(
"Input frame size is larger than buffer frame size (input: " << inputFrameSizeInBytes <<
", buffer: " << bufferFrameSizeBytes <<
")!");
606 newObjectInBuffer->
SetIndex(frameNumber);
607 newObjectInBuffer->
SetUid(itemUid);
608 newObjectInBuffer->
GetFrame().SetImageType(imageType);
609 memcpy(newObjectInBuffer->
GetFrame().GetImage()->GetScalarPointer(), imageDataPtr, inputFrameSizeInBytes);
612 if (customFields != NULL)
614 for (igsioFieldMapType::const_iterator it = customFields->begin(); it != customFields->end(); ++it)
616 newObjectInBuffer->
SetFrameField(it->first, it->second.second, it->second.first);
617 std::string name(it->first);
618 if (name.find(
"Transform") != std::string::npos)
625 newObjectInBuffer->
SetFrameField(
"FrameSizeInBytes", igsioCommon::ToString<unsigned int>(inputFrameSizeInBytes));
635 LOCAL_LOG_ERROR(
"vtkPlusBuffer: Unable to add NULL matrix to tracker buffer!");
638 if (unfilteredTimestamp == UNDEFINED_TIMESTAMP)
640 unfilteredTimestamp = vtkIGSIOAccurateTimer::GetSystemTime();
642 if (filteredTimestamp == UNDEFINED_TIMESTAMP)
644 bool filteredTimestampProbablyValid =
true;
647 LOCAL_LOG_DEBUG(
"Failed to create filtered timestamp for tracker buffer item with item index: " << frameNumber);
650 if (!filteredTimestampProbablyValid)
652 LOG_INFO(
"Filtered timestamp is probably invalid for tracker buffer item with item index=" << frameNumber <<
", time=" << unfilteredTimestamp <<
". The item may have been tagged with an inaccurate timestamp, therefore it will not be recorded.");
664 igsioLockGuard<StreamItemCircularBuffer> dataBufferGuardedLock(this->
StreamBuffer);
668 LOCAL_LOG_DEBUG(
"vtkPlusBuffer: Failed to prepare for adding new frame to tracker buffer!");
674 if (newObjectInBuffer == NULL)
676 LOCAL_LOG_ERROR(
"vtkPlusBuffer: Failed to get pointer to data buffer object from the tracker buffer for the new frame!");
684 newObjectInBuffer->
SetIndex(frameNumber);
685 newObjectInBuffer->
SetUid(itemUid);
688 if (customFields != NULL)
690 for (igsioFieldMapType::const_iterator it = customFields->begin(); it != customFields->end(); ++it)
692 newObjectInBuffer->
SetFrameField(it->first, it->second.second, it->second.first);
693 std::string name(it->first);
694 if (name.find(
"Transform") != std::string::npos)
768 if (bufferItem == NULL)
770 LOCAL_LOG_ERROR(
"Unable to copy data buffer item into a NULL data buffer item!");
774 igsioLockGuard<StreamItemCircularBuffer> dataBufferGuardedLock(this->
StreamBuffer);
796 LOG_TRACE(
"vtkPlusBuffer::DeepCopy");
819 if (
x != 0 &&
y != 0 && z == 0)
842 return SetFrameSize(frameSize[0], frameSize[1], frameSize[2], allocateFrames);
872 if (imgType < US_IMG_TYPE_XX || imgType >= US_IMG_TYPE_LAST)
874 LOCAL_LOG_ERROR(
"Invalid image type attempted to set in the video buffer: " << imgType);
884 if (imgOrientation < US_IMG_ORIENT_XX || imgOrientation >= US_IMG_ORIENT_LAST)
886 LOCAL_LOG_ERROR(
"Invalid image orientation attempted to set in the video buffer: " << imgOrientation);
900 return igsioVideoFrame::GetNumberOfBytesPerScalar(
GetPixelType());
912 int numberOfErrors = 0;
914 const int numberOfVideoFrames = sourceTrackedFrameList->GetNumberOfTrackedFrames();
915 LOCAL_LOG_DEBUG(
"CopyImagesFromTrackedFrameList will copy " << numberOfVideoFrames <<
" frames");
917 FrameSizeType frameSize = {0, 0, 0};
918 sourceTrackedFrameList->GetTrackedFrame(0)->GetImageData()->GetFrameSize(frameSize);
919 bool isFrameEncoded = sourceTrackedFrameList->GetTrackedFrame(0)->GetImageData()->IsFrameEncoded();
923 this->
SetPixelType(sourceTrackedFrameList->GetTrackedFrame(0)->GetImageData()->GetVTKScalarPixelType());
925 unsigned int numberOfScalarComponents(1);
926 if (sourceTrackedFrameList->GetTrackedFrame(0)->GetImageData()->GetNumberOfScalarComponents(numberOfScalarComponents) !=
PLUS_SUCCESS)
928 LOG_ERROR(
"Unable to retrieve number of scalar components.");
939 bool requireTimestamp =
false;
942 requireTimestamp =
true;
945 bool requireUnfilteredTimestamp =
false;
948 requireUnfilteredTimestamp =
true;
951 bool requireFrameStatus =
false;
952 bool requireFrameNumber =
false;
956 requireFrameStatus =
true;
957 requireFrameNumber =
true;
960 LOG_INFO(
"Copy buffer to video buffer...");
961 for (
int frameNumber = 0; frameNumber < numberOfVideoFrames; frameNumber++)
963 igsioFieldMapType customFields;
967 igsioFieldMapType sourceCustomFields = sourceTrackedFrameList->GetTrackedFrame(frameNumber)->GetCustomFields();
968 igsioFieldMapType::iterator fieldIterator;
969 for (fieldIterator = sourceCustomFields.begin(); fieldIterator != sourceCustomFields.end(); fieldIterator++)
972 if (igsioCommon::IsEqualInsensitive(fieldIterator->first,
"TimeStamp"))
976 if (igsioCommon::IsEqualInsensitive(fieldIterator->first,
"UnfilteredTimestamp"))
980 if (igsioCommon::IsEqualInsensitive(fieldIterator->first,
"FrameNumber"))
985 customFields[fieldIterator->first] = fieldIterator->second;
991 std::string strTimestamp = sourceTrackedFrameList->GetTrackedFrame(frameNumber)->GetFrameField(
"Timestamp");
992 if (!strTimestamp.empty())
994 if (igsioCommon::StringToNumber<double>(strTimestamp,
timestamp) !=
PLUS_SUCCESS && requireTimestamp)
996 LOCAL_LOG_ERROR(
"Unable to convert Timestamp '" << strTimestamp <<
"' to double for frame #" << frameNumber);
1001 else if (requireTimestamp)
1003 LOCAL_LOG_ERROR(
"Unable to read Timestamp field of frame #" << frameNumber);
1009 double unfilteredtimestamp(0);
1010 std::string strUnfilteredTimestamp = sourceTrackedFrameList->GetTrackedFrame(frameNumber)->GetFrameField(
"UnfilteredTimestamp");
1011 if (!strUnfilteredTimestamp.empty())
1013 if (igsioCommon::StringToNumber<double>(strUnfilteredTimestamp, unfilteredtimestamp) !=
PLUS_SUCCESS && requireUnfilteredTimestamp)
1015 LOCAL_LOG_ERROR(
"Unable to convert UnfilteredTimestamp '" << strUnfilteredTimestamp <<
"' to double for frame #" << frameNumber);
1020 else if (requireUnfilteredTimestamp)
1022 LOCAL_LOG_ERROR(
"Unable to read UnfilteredTimestamp field of frame #" << frameNumber);
1028 const std::string strFrameNumber = sourceTrackedFrameList->GetTrackedFrame(frameNumber)->GetFrameField(
"FrameNumber");
1029 unsigned long frmnum(0);
1030 if (!strFrameNumber.empty())
1032 if (igsioCommon::StringToNumber<unsigned long>(strFrameNumber, frmnum) !=
PLUS_SUCCESS && requireFrameNumber)
1034 LOCAL_LOG_ERROR(
"Unable to convert FrameNumber '" << strFrameNumber <<
"' to integer for frame #" << frameNumber);
1039 else if (requireFrameNumber)
1041 LOCAL_LOG_ERROR(
"Unable to read FrameNumber field of frame #" << frameNumber);
1046 std::array<int, 3> clipRectOrigin = {igsioCommon::NO_CLIP, igsioCommon::NO_CLIP, igsioCommon::NO_CLIP};
1047 std::array<int, 3> clipRectSize = {igsioCommon::NO_CLIP, igsioCommon::NO_CLIP, igsioCommon::NO_CLIP};
1048 switch (timestampFiltering)
1051 if (this->
AddItem(sourceTrackedFrameList->GetTrackedFrame(frameNumber)->GetImageData(), frmnum, clipRectOrigin, clipRectSize, unfilteredtimestamp,
timestamp, &customFields) !=
PLUS_SUCCESS)
1053 LOCAL_LOG_WARNING(
"Failed to add video frame to buffer from sequence metafile with frame #" << frameNumber);
1057 if (this->
AddItem(sourceTrackedFrameList->GetTrackedFrame(frameNumber)->GetImageData(), frmnum, clipRectOrigin, clipRectSize, unfilteredtimestamp, UNDEFINED_TIMESTAMP, &customFields) !=
PLUS_SUCCESS)
1059 LOCAL_LOG_WARNING(
"Failed to add video frame to buffer from sequence metafile with frame #" << frameNumber);
1065 LOCAL_LOG_WARNING(
"Failed to add video frame to buffer from sequence metafile with frame #" << frameNumber);
1079 LOG_TRACE(
"vtkPlusBuffer::WriteToSequenceFile");
1081 vtkSmartPointer<vtkIGSIOTrackedFrameList> trackedFrameList = vtkSmartPointer<vtkIGSIOTrackedFrameList>::New();
1090 LOCAL_LOG_ERROR(
"Unable to get frame from buffer with UID: " << frameUid);
1095 igsioTrackedFrame* trackedFrame =
new igsioTrackedFrame;
1098 trackedFrame->SetImageData(bufferItem.
GetFrame());
1101 vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
1103 trackedFrame->SetFrameTransform(igsioTransformName(
"Tool",
"Tracker"), matrix);
1104 trackedFrame->SetFrameTransformStatus(igsioTransformName(
"Tool",
"Tracker"), bufferItem.
GetStatus());
1108 std::ostringstream timestampFieldValue;
1109 timestampFieldValue << std::fixed << filteredTimestamp;
1110 trackedFrame->SetFrameField(
"Timestamp", timestampFieldValue.str());
1114 std::ostringstream unfilteredtimestampFieldValue;
1115 unfilteredtimestampFieldValue << std::fixed << unfilteredTimestamp;
1116 trackedFrame->SetFrameField(
"UnfilteredTimestamp", unfilteredtimestampFieldValue.str());
1119 unsigned long frameNumber = bufferItem.
GetIndex();
1120 std::ostringstream frameNumberFieldValue;
1121 frameNumberFieldValue << std::fixed << frameNumber;
1122 trackedFrame->SetFrameField(
"FrameNumber", frameNumberFieldValue.str());
1126 for (igsioFieldMapType::const_iterator cf = customFields.begin(); cf != customFields.end(); ++cf)
1128 trackedFrame->SetFrameField(cf->first, cf->second.second, cf->second.first);
1132 trackedFrameList->TakeTrackedFrame(trackedFrame);
1138 LOCAL_LOG_ERROR(
"Failed to save tracked frames to sequence metafile!");
1162 igsioLockGuard<StreamItemCircularBuffer> dataBufferGuardedLock(this->
StreamBuffer);
1179 LOCAL_LOG_DEBUG(
"vtkPlusBuffer: Cannot get any item from the data buffer for time: " << std::fixed <<
time <<
". Item is not available yet.");
1182 LOCAL_LOG_DEBUG(
"vtkPlusBuffer: Cannot get any item from the data buffer for time: " << std::fixed <<
time <<
". Item is not available anymore.");
1192 LOCAL_LOG_ERROR(
"vtkPlusBuffer: Failed to get data buffer item with Uid: " << itemAuid);
1200 LOCAL_LOG_DEBUG(
"vtkPlusBuffer: Cannot do data interpolation. The closest item to the requested time (time: " << std::fixed <<
time <<
", uid: " << itemAuid <<
") is invalid.");
1204 double itemAtime(0);
1208 LOCAL_LOG_ERROR(
"vtkPlusBuffer: Failed to get data buffer timestamp (time: " << std::fixed <<
time <<
", uid: " << itemAuid <<
")");
1223 LOCAL_LOG_ERROR(
"vtkPlusBuffer: Cannot perform interpolation, time difference compared to itemA is too big " << std::fixed << fabs(itemAtime -
time) <<
" ( closest item time: " << itemAtime <<
", requested time: " <<
time <<
").");
1229 if (
time < itemAtime)
1232 itemBuid = itemAuid - 1;
1237 itemBuid = itemAuid + 1;
1246 double itemBtime(0);
1250 LOCAL_LOG_ERROR(
"Cannot do interpolation: Failed to get data buffer timestamp with Uid: " << itemBuid);
1256 LOCAL_LOG_ERROR(
"vtkPlusBuffer: Cannot perform interpolation, time difference compared to itemB is too big " << std::fixed << fabs(itemBtime -
time) <<
" ( itemBtime: " << itemBtime <<
", requested time: " <<
time <<
").");
1263 LOCAL_LOG_ERROR(
"vtkPlusBuffer: Failed to get data buffer item with Uid: " << itemBuid);
1269 LOCAL_LOG_DEBUG(
"vtkPlusBuffer: Cannot get a second element (uid=" << itemBuid <<
") on the other side of the requested time (" << std::fixed <<
time <<
")");
1279 switch (interpolation)
1288 LOCAL_LOG_WARNING(
"Unknown interpolation type: " << interpolation <<
". Defaulting to exact time request.");
1311 LOCAL_LOG_WARNING(
"vtkPlusBuffer: Failed to get data buffer timestamp (time: " << std::fixed <<
time <<
")");
1319 LOCAL_LOG_WARNING(
"vtkPlusBuffer: Cannot find an item exactly at the requested time (requested time: " << std::fixed <<
time <<
", item time: " << itemTime <<
")");
1329 igsioLockGuard<StreamItemCircularBuffer> dataBufferGuardedLock(this->
StreamBuffer);
1338 LOCAL_LOG_WARNING(
"vtkPlusBuffer: Cannot get any item from the buffer for time: " << std::fixed <<
time <<
". Item is not available yet.");
1341 LOCAL_LOG_WARNING(
"vtkPlusBuffer: Cannot get any item from the buffer for time: " << std::fixed <<
time <<
". Item is not available anymore.");
1352 LOCAL_LOG_ERROR(
"vtkPlusBuffer: Failed to get buffer item with Uid: " << itemUid);
1380 LOCAL_LOG_ERROR(
"vtkPlusBuffer: Failed to get data buffer timestamp (time: " << std::fixed <<
time <<
")");
1396 double itemAtime(0);
1399 LOCAL_LOG_ERROR(
"vtkPlusBuffer: Failed to get data buffer timestamp (time: " << std::fixed <<
time <<
", uid: " << itemA.
GetUid() <<
")");
1403 double itemBtime(0);
1406 LOCAL_LOG_ERROR(
"vtkPlusBuffer: Failed to get data buffer timestamp (time: " << std::fixed <<
time <<
", uid: " << itemB.
GetUid() <<
")");
1419 double itemAweight = fabs(itemBtime -
time) / fabs(itemAtime - itemBtime);
1420 double itemBweight = 1 - itemAweight;
1424 vtkSmartPointer<vtkMatrix4x4> itemAmatrix = vtkSmartPointer<vtkMatrix4x4>::New();
1430 double matrixA[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
1431 double xyzA[3] = {0, 0, 0};
1432 for (
int i = 0;
i < 3;
i++)
1434 matrixA[
i][0] = itemAmatrix->GetElement(
i, 0);
1435 matrixA[
i][1] = itemAmatrix->GetElement(
i, 1);
1436 matrixA[
i][2] = itemAmatrix->GetElement(
i, 2);
1437 xyzA[
i] = itemAmatrix->GetElement(
i, 3);
1440 vtkSmartPointer<vtkMatrix4x4> itemBmatrix = vtkSmartPointer<vtkMatrix4x4>::New();
1446 double matrixB[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
1447 double xyzB[3] = {0, 0, 0};
1448 for (
int i = 0;
i < 3;
i++)
1450 matrixB[
i][0] = itemBmatrix->GetElement(
i, 0);
1451 matrixB[
i][1] = itemBmatrix->GetElement(
i, 1);
1452 matrixB[
i][2] = itemBmatrix->GetElement(
i, 2);
1453 xyzB[
i] = itemBmatrix->GetElement(
i, 3);
1458 double matrixAquat[4] = {0, 0, 0, 0};
1459 vtkMath::Matrix3x3ToQuaternion(matrixA, matrixAquat);
1460 double matrixBquat[4] = {0, 0, 0, 0};
1461 vtkMath::Matrix3x3ToQuaternion(matrixB, matrixBquat);
1462 double interpolatedRotationQuat[4] = {0, 0, 0, 0};
1463 igsioMath::Slerp(interpolatedRotationQuat, itemBweight, matrixAquat, matrixBquat);
1464 double interpolatedRotation[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
1465 vtkMath::QuaternionToMatrix3x3(interpolatedRotationQuat, interpolatedRotation);
1467 vtkSmartPointer<vtkMatrix4x4> interpolatedMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
1468 for (
int i = 0;
i < 3;
i++)
1470 interpolatedMatrix->Element[
i][0] = interpolatedRotation[
i][0];
1471 interpolatedMatrix->Element[
i][1] = interpolatedRotation[
i][1];
1472 interpolatedMatrix->Element[
i][2] = interpolatedRotation[
i][2];
1473 interpolatedMatrix->Element[
i][3] = xyzA[
i] * itemAweight + xyzB[
i] * itemBweight;
1480 double interpolatedUnfilteredTimestamp = itemAunfilteredTimestamp * itemAweight + itemBunfilteredTimestamp * itemBweight;
1485 bufferItem->
SetMatrix(interpolatedMatrix);
1489 double angleDiffA = igsioMath::GetOrientationDifference(interpolatedMatrix, itemAmatrix);
1490 double angleDiffB = igsioMath::GetOrientationDifference(interpolatedMatrix, itemBmatrix);
1493 static vtkIGSIOLogHelper helper(5.f, 5000, vtkPlusLogger::LOG_LEVEL_WARNING);
1494 if (helper.ShouldWeLog(
true))
1496 LOCAL_LOG_WARNING(
"Angle difference between interpolated orientations is large (" << fabs(angleDiffA) <<
" and " << fabs(angleDiffB) <<
" deg, warning threshold is " <<
ANGLE_INTERPOLATION_WARNING_THRESHOLD_DEG <<
"), interpolation may be inaccurate. Consider moving the tools slower.");
1506 int numberOfErrors = 0;
1508 int numberOfFrames = sourceTrackedFrameList->GetNumberOfTrackedFrames();
1511 bool requireTimestamp =
false;
1514 requireTimestamp =
true;
1517 bool requireUnfilteredTimestamp =
false;
1520 requireUnfilteredTimestamp =
true;
1523 bool requireFrameStatus =
false;
1524 bool requireFrameNumber =
false;
1528 requireFrameStatus =
true;
1529 requireFrameNumber =
true;
1532 for (
int frameNumber = 0; frameNumber < numberOfFrames; frameNumber++)
1537 const std::string strTimestamp = sourceTrackedFrameList->GetTrackedFrame(frameNumber)->GetFrameField(
"Timestamp");
1538 if (!strTimestamp.empty())
1540 if (igsioCommon::StringToNumber<double>(strTimestamp,
timestamp) !=
PLUS_SUCCESS && requireTimestamp)
1542 LOCAL_LOG_ERROR(
"Unable to convert Timestamp '" << strTimestamp <<
"' to double");
1547 else if (requireTimestamp)
1549 LOCAL_LOG_ERROR(
"Unable to read Timestamp field of frame #" << frameNumber);
1555 double unfilteredtimestamp(0);
1556 const std::string strUnfilteredTimestamp = sourceTrackedFrameList->GetTrackedFrame(frameNumber)->GetFrameField(
"UnfilteredTimestamp");
1557 if (!strUnfilteredTimestamp.empty())
1559 if (igsioCommon::StringToNumber<double>(strUnfilteredTimestamp, unfilteredtimestamp) !=
PLUS_SUCCESS && requireUnfilteredTimestamp)
1561 LOCAL_LOG_ERROR(
"Unable to convert UnfilteredTimestamp '" << strUnfilteredTimestamp <<
"' to double");
1566 else if (requireUnfilteredTimestamp)
1568 LOCAL_LOG_ERROR(
"Unable to read UnfilteredTimestamp field of frame #" << frameNumber);
1574 ToolStatus toolStatus(TOOL_OK);
1575 if (sourceTrackedFrameList->GetTrackedFrame(frameNumber)->GetFrameTransformStatus(transformName, toolStatus) !=
PLUS_SUCCESS && requireFrameStatus)
1577 LOCAL_LOG_ERROR(
"Unable to read TransformStatus field of frame #" << frameNumber);
1583 const std::string strFrameNumber = sourceTrackedFrameList->GetTrackedFrame(frameNumber)->GetFrameField(
"FrameNumber");
1584 unsigned long frmnum(0);
1585 if (!strFrameNumber.empty())
1587 if (igsioCommon::StringToNumber<unsigned long>(strFrameNumber, frmnum) !=
PLUS_SUCCESS && requireFrameNumber)
1589 LOCAL_LOG_ERROR(
"Unable to convert FrameNumber '" << strFrameNumber <<
"' to integer for frame #" << frameNumber);
1594 else if (requireFrameNumber)
1596 LOCAL_LOG_ERROR(
"Unable to read FrameNumber field of frame #" << frameNumber);
1601 double copiedTransform[16] = {0};
1602 if (!sourceTrackedFrameList->GetTrackedFrame(frameNumber)->GetFrameTransform(transformName, copiedTransform))
1604 std::string strTransformName;
1605 transformName.GetTransformName(strTransformName);
1606 LOCAL_LOG_ERROR(
"Unable to get the " << strTransformName <<
" frame transform for frame #" << frameNumber);
1611 vtkSmartPointer<vtkMatrix4x4> copiedTransformMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
1612 copiedTransformMatrix->DeepCopy(copiedTransform);
1614 switch (timestampFiltering)
1620 this->
AddTimeStampedItem(copiedTransformMatrix, toolStatus, frmnum, unfilteredtimestamp);
1668 #undef LOCAL_LOG_ERROR 1669 #undef LOCAL_LOG_WARNING 1670 #undef LOCAL_LOG_DEBUG ItemStatus GetBufferIndexFromTime(const double time, int &bufferIndex)
void SetTimeStampReporting(bool enable)
virtual void SetStartTime(double)
virtual ItemStatus GetBufferItemPointerFromUid(const BufferItemUidType uid, StreamBufferItem *&itemPtr)
ToolStatus GetStatus() const
PlusStatus SetImageType(US_IMAGE_TYPE imageType)
TIMESTAMP_FILTERING_OPTION
DataItemTemporalInterpolationType
static const double NEGLIGIBLE_TIME_DIFFERENCE
virtual US_IMAGE_ORIENTATION GetImageOrientation()
virtual ItemStatus GetLatestTimeStamp(double ×tamp)
virtual void SetLocalTimeOffsetSec(double)
virtual FrameSizeType GetFrameSize() const
virtual void DeepCopy(vtkPlusTimestampedCircularBuffer *buffer)
virtual void SetStartTime(double startTime)
virtual double GetLocalTimeOffsetSec()
PlusStatus SetImageOrientation(US_IMAGE_ORIENTATION imageOrientation)
virtual PlusStatus ModifyBufferItemFrameField(BufferItemUidType uid, const std::string &key, const std::string &value)
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
virtual PlusStatus PrepareForNewItem(const double timestamp, BufferItemUidType &newFrameUid, int &bufferIndex)
virtual bool GetTimeStampReporting()
void SetFilteredTimestamp(double filteredTimestamp)
This class stores an fixed number of timestamped items. It provides element retrieval based on timest...
virtual double GetLocalTimeOffsetSec()
US_IMAGE_ORIENTATION ImageOrientation
virtual PlusStatus SetBufferSize(int n)
virtual int GetBufferSize()
virtual igsioCommon::VTKScalarPixelType GetPixelType()
void SetUid(BufferItemUidType uid)
#define LOCAL_LOG_WARNING(msg)
void SetValidTransformData(bool aValid)
virtual PlusStatus SetBufferSize(int n)
virtual bool GetLatestItemHasValidFieldData()
virtual void DeepCopy(vtkPlusBuffer *buffer)
virtual PlusStatus AddItem(vtkImageData *frame, US_IMAGE_ORIENTATION usImageOrientation, US_IMAGE_TYPE imageType, long frameNumber, const std::array< int, 3 > &clipRectangleOrigin, const std::array< int, 3 > &clipRectangleSize, double unfilteredTimestamp=UNDEFINED_TIMESTAMP, double filteredTimestamp=UNDEFINED_TIMESTAMP, const igsioFieldMapType *customFields=NULL)
virtual ItemStatus GetItemUidFromTime(const double time, BufferItemUidType &uid)
igsioFieldMapType GetFrameFieldMap()
virtual PlusStatus CreateFilteredTimeStampForItem(unsigned long itemIndex, double inUnfilteredTimestamp, double &outFilteredTimestamp, bool &filteredTimestampProbablyValid)
virtual BufferItemUidType GetLatestItemUidInBuffer()
double GetFilteredTimestamp(double localTimeOffsetSec)
virtual ItemStatus GetOldestTimeStamp(double &oldestTimestamp)
static igsioStatus Write(const std::string &filename, igsioTrackedFrame *frame, US_IMAGE_ORIENTATION orientationInFile=US_IMG_ORIENT_MF, bool useCompression=true, bool EnableImageDataWrite=true)
virtual void SetAveragedItemsForFiltering(unsigned int)
PlusStatus GetPrevNextBufferItemFromTime(double time, StreamBufferItem &itemA, StreamBufferItem &itemB)
virtual void SetDescriptiveName(const char *)
virtual bool CheckFrameFormat(const FrameSizeType &frameSizeInPx, igsioCommon::VTKScalarPixelType pixelType, US_IMAGE_TYPE imgType, int numberOfScalarComponents)
void PrintSelf(ostream &os, vtkIndent indent)
PlusStatus GetTimeStampReportTable(vtkTable *timeStampReportTable)
virtual int GetAveragedItemsForFiltering()
virtual unsigned int GetNumberOfScalarComponents()
virtual double GetStartTime()
virtual bool GetLatestItemHasValidFieldData()
virtual double GetMaxAllowedTimeDifference()
virtual void SetLocalTimeOffsetSec(double offsetSec)
virtual ItemStatus GetStreamBufferItemFromTime(double time, StreamBufferItem *bufferItem, DataItemTemporalInterpolationType interpolation)
void SetIndex(unsigned long index)
unsigned int NumberOfScalarComponents
PlusStatus GetMatrix(vtkMatrix4x4 *outputMatrix)
PlusStatus SetFrameSize(unsigned int x, unsigned int y, unsigned int z, bool allocateFrames=true)
PlusStatus SetPixelType(igsioCommon::VTKScalarPixelType pixelType)
virtual PlusStatus GetTimeStampReportTable(vtkTable *timeStampReportTable)
void AddToTimeStampReport(unsigned long itemIndex, double unfilteredTimestamp, double filteredTimestamp)
double GetUnfilteredTimestamp(double localTimeOffsetSec)
virtual US_IMAGE_TYPE GetImageType()
virtual bool GetLatestItemHasValidTransformData()
virtual int GetBufferSize()
igsioVideoFrame & GetFrame()
virtual ItemStatus GetTimeStamp(BufferItemUidType uid, double ×tamp)
PlusStatus DeepCopy(StreamBufferItem *dataItem)
void SetFrameField(std::string fieldName, std::string fieldValue, igsioFrameFieldFlags flags=FRAMEFIELD_NONE)
virtual ItemStatus GetOldestTimeStamp(double ×tamp)
const char const char * value
StreamItemCircularBuffer * StreamBuffer
virtual int GetAveragedItemsForFiltering()
virtual void SetTimeStampReporting(bool)
PlusStatus SetMatrix(vtkMatrix4x4 *matrix)
virtual ItemStatus GetIndex(const BufferItemUidType uid, unsigned long &index)
BufferItemUidType GetUid()
virtual ItemStatus GetStreamBufferItem(BufferItemUidType uid, StreamBufferItem *bufferItem)
virtual ItemStatus GetStreamBufferItemFromExactTime(double time, StreamBufferItem *bufferItem)
igsioCommon::VTKScalarPixelType PixelType
virtual bool GetLatestItemHasValidTransformData()
virtual ItemStatus GetBufferIndexFromTime(const double time, int &bufferIndex)
void SetUnfilteredTimestamp(double unfilteredTimestamp)
#define LOCAL_LOG_DEBUG(msg)
Direction vectors of rods y
virtual ItemStatus GetLatestTimeStamp(double &latestTimestamp)
virtual StreamBufferItem * GetBufferItemPointerFromBufferIndex(const int bufferIndex)
virtual ItemStatus GetIndex(const BufferItemUidType uid, unsigned long &index)
virtual ItemStatus GetTimeStamp(const BufferItemUidType uid, double ×tamp)
virtual void SetAveragedItemsForFiltering(int averagedItemsForFiltering)
vtkStandardNewMacro(vtkPlusBuffer)
PlusStatus CopyImagesFromTrackedFrameList(vtkIGSIOTrackedFrameList *sourceTrackedFrameList, TIMESTAMP_FILTERING_OPTION timestampFiltering, bool copyFrameFields)
virtual BufferItemUidType GetOldestItemUidInBuffer()
bool GetTimeStampReporting()
virtual ItemStatus GetStreamBufferItemFromClosestTime(double time, StreamBufferItem *bufferItem)
int GetNumberOfBytesPerScalar()
unsigned long long BufferItemUidType
void SetStatus(ToolStatus status)
virtual double GetStartTime()
virtual PlusStatus AllocateMemoryForFrames()
static const double ANGLE_INTERPOLATION_WARNING_THRESHOLD_DEG
PlusStatus SetNumberOfScalarComponents(unsigned int numberOfScalarComponents)
int GetNumberOfBytesPerPixel()
virtual bool GetLatestItemHasValidVideoData()
virtual ItemStatus GetInterpolatedStreamBufferItemFromTime(double time, StreamBufferItem *bufferItem)
virtual bool GetLatestItemHasValidVideoData()
virtual PlusStatus WriteToSequenceFile(const char *filename, bool useCompression=false)
PlusStatus AddTimeStampedItem(vtkMatrix4x4 *matrix, ToolStatus status, unsigned long frameNumber, double unfilteredTimestamp, double filteredTimestamp=UNDEFINED_TIMESTAMP, const igsioFieldMapType *customFields=NULL)
PlusStatus CopyTransformFromTrackedFrameList(vtkIGSIOTrackedFrameList *sourceTrackedFrameList, TIMESTAMP_FILTERING_OPTION timestampFiltering, igsioTransformName &transformName)
#define LOCAL_LOG_ERROR(msg)