17 #include "PlusConfigure.h" 18 #include "vtkObjectFactory.h" 26 #include "StreamMgr.h" 34 #include <arpa/inet.h> 45 vtkImageData* streamedImageData = NULL;
46 static double LastValidTimestamp(0);
47 static double LastRetryTime(0);
49 const double TIMEOUT = 1.0;
50 const double RETRY_TIMER = 0.5;
54 bool vtkPlusPhilips3DProbeVideoSource::StreamCallback(_int64
id, SClient3DArray* ed, SClient3DArray* cd)
56 if (vtkPlusPhilips3DProbeVideoSource::ActiveDevice == NULL)
58 LOG_ERROR(
"No Philips device has been created, but the callback was still called.");
62 int dimensions[3] = {ed->width_padded, ed->height_padded, ed->depth_padded};
70 if (streamedImageData == NULL)
73 double spacing[3] = {1.0, 1.0, 1.0};
74 double origin[3] = {0.0, 0.0, 0.0};
76 streamedImageData = vtkImageData::New();
77 streamedImageData->SetSpacing(spacing);
78 streamedImageData->SetExtent(0, dimensions[0] - 1, 0, dimensions[1] - 1, 0, dimensions[2] - 1);
79 streamedImageData->SetOrigin(origin);
80 #if VTK_MAJOR_VERSION > 5 81 streamedImageData->AllocateScalars(VTK_UNSIGNED_CHAR, 1);
83 streamedImageData->SetScalarTypeToUnsignedChar();
84 streamedImageData->SetNumberOfScalarComponents(1);
85 streamedImageData->AllocateScalars();
90 if (dimensions[0] < 0 || dimensions[1] < 0 || dimensions[2] < 0)
92 LOG_ERROR(
"Negative dimensions received from Philips ultrasound device.");
95 videoSource->SetInputFrameSize(static_cast<unsigned int>(dimensions[0]), static_cast<unsigned int>(dimensions[1]), static_cast<unsigned int>(dimensions[2]));
96 videoSource->SetPixelType(VTK_UNSIGNED_CHAR);
97 videoSource->SetNumberOfScalarComponents(1);
101 int streamedDimensions[3] = {0, 0, 0};
102 streamedImageData->GetDimensions(streamedDimensions);
104 if (dimensions[0] != streamedDimensions[0] || dimensions[1] != streamedDimensions[1] || dimensions[2] != streamedDimensions[2])
106 LOG_ERROR(
"Dimensions of new frame do not match dimensions of previous frames. Cannot add frame to buffer.");
111 size_t size = dimensions[0] * dimensions[1] * dimensions[2];
112 unsigned char*
src = ed->pData;
113 unsigned char* dst = (
unsigned char*)streamedImageData->GetScalarPointer();
115 memcpy((
void*)dst, (
void*)
src, size);
117 vtkPlusPhilips3DProbeVideoSource::ActiveDevice->
CallbackAddFrame(streamedImageData);
119 LastValidTimestamp = vtkIGSIOAccurateTimer::GetSystemTime();
134 , ForceZQuantize(false)
135 , ResolutionFactor(2.5)
141 , LatAndElevSmoothingIndex(4)
148 if (vtkPlusPhilips3DProbeVideoSource::ActiveDevice != NULL)
150 LOG_WARNING(
"There is already an active vtkPlusPhilips3DProbeVideoSource device. Philips API only supports one connection at a time, so the existing device is now deactivated and the newly created class is activated instead.");
153 vtkPlusPhilips3DProbeVideoSource::ActiveDevice =
this;
170 vtkPlusPhilips3DProbeVideoSource::ActiveDevice = NULL;
187 LOG_TRACE(
"vtkPlusPhilips3DProbeVideoSource::InternalConnect");
194 LOG_ERROR(
"Unable to connect to Philips device.");
204 LOG_TRACE(
"vtkPlusPhilips3DProbeVideoSource::InternalDisconnect");
208 if (streamedImageData != NULL)
210 streamedImageData->Delete();
211 streamedImageData = NULL;
223 if (vtkIGSIOAccurateTimer::GetSystemTime() - LastValidTimestamp >= TIMEOUT)
225 LOG_INFO(
"Philips iE33: 3D mode timeout disconnected. Did you switch to another mode?");
229 LastRetryTime = vtkIGSIOAccurateTimer::GetSystemTime();
232 else if (vtkIGSIOAccurateTimer::GetSystemTime() - LastRetryTime >= RETRY_TIMER)
234 LOG_INFO(
"Philips iE33: Retrying connection to 3D mode.");
236 LastRetryTime = vtkIGSIOAccurateTimer::GetSystemTime();
237 if (this->
Listener->
Connect(&vtkPlusPhilips3DProbeVideoSource::StreamCallback, vtkPlusLogger::LOG_LEVEL_WARNING))
239 LOG_INFO(
"Philips iE33: Connection successfully re-established.");
240 LastValidTimestamp = vtkIGSIOAccurateTimer::GetSystemTime();
250 LOG_TRACE(
"vtkPlusPhilips3DProbeVideoSource::ReadConfiguration");
253 XML_READ_SCALAR_ATTRIBUTE_REQUIRED(
int,
Port, deviceConfig);
254 XML_READ_CSTRING_ATTRIBUTE_REQUIRED(
IPAddress, deviceConfig);
257 int result = InetPton(AF_INET, this->
IPAddress, &address);
260 int result = inet_pton(AF_INET, this->
IPAddress, &(address.sin_addr));
264 LOG_ERROR(
"Improperly formatted IPAddress. Please confirm formatting in config file.");
270 XML_READ_BOOL_ATTRIBUTE_OPTIONAL(
IntegerZ, deviceConfig);
271 XML_READ_BOOL_ATTRIBUTE_OPTIONAL(
Isotropic, deviceConfig);
272 XML_READ_BOOL_ATTRIBUTE_OPTIONAL(
QuantizeDim, deviceConfig);
273 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
int,
ZDecimation, deviceConfig);
274 XML_READ_BOOL_ATTRIBUTE_OPTIONAL(
Set4PtFIR, deviceConfig);
283 LOG_TRACE(
"vtkPlusPhilips3DProbeVideoSource::WriteConfiguration");
286 XML_WRITE_CSTRING_ATTRIBUTE_IF_NOT_NULL(
IPAddress, deviceConfig);
287 deviceConfig->SetIntAttribute(
"Port", this->
Port);
289 deviceConfig->SetDoubleAttribute(
"ResolutionFactor", this->
ResolutionFactor);
290 deviceConfig->SetIntAttribute(
"ZDecimation", this->
ZDecimation);
293 XML_WRITE_BOOL_ATTRIBUTE(
IntegerZ, deviceConfig);
294 XML_WRITE_BOOL_ATTRIBUTE(
Isotropic, deviceConfig);
295 XML_WRITE_BOOL_ATTRIBUTE(
QuantizeDim, deviceConfig);
296 XML_WRITE_BOOL_ATTRIBUTE(
Set4PtFIR, deviceConfig);
305 LOG_WARNING(
"vtkPlusPhilips3DProbeVideoSource is expecting one output channel and there are " << this->
OutputChannels.size() <<
" channels. First output channel will be used.");
312 LOG_ERROR(
"No output channels defined for vtkPlusPhilips3DProbeVideoSource. Cannot proceed.");
320 LOG_ERROR(
"Unable to find video source. Device needs a video buffer to put new frames into.");
346 LOG_ERROR(
"Unable to find video source. Cannot add new frame.");
350 std::future<void> addTask = std::async(std::launch::async, [ = ]()
354 LOG_ERROR(
"Unable to add item to buffer.");
358 std::future<uint8_t> maxPixelTask = std::async(std::launch::async, [ = ]()
361 imageData->GetExtent(extent);
362 uint8_t* pixelPtr = (uint8_t*)imageData->GetScalarPointer();
363 auto numComponents = imageData->GetNumberOfScalarComponents();
365 uint8_t maxPixelValue(0);
366 for (
int z = 0; z < extent[5] - extent[4]; ++z)
368 for (
int y = 0;
y < extent[3] - extent[2]; ++
y)
370 for (
int x = 0;
x < extent[1] - extent[0]; ++
x)
372 if (*pixelPtr > maxPixelValue)
374 maxPixelValue = *pixelPtr;
376 pixelPtr += numComponents;
381 return maxPixelValue;
385 unsigned int maxPixelValue = static_cast<unsigned int>(maxPixelTask.get());
387 std::stringstream ss;
virtual BufferItemUidType GetLatestItemUidInBuffer()
void SetPortNumber(unsigned int port)
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *config)
virtual PlusStatus InternalUpdate()
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_WRITING(deviceConfig, rootConfigElement)
static vtkPlusIEEListener * New()
const char int const char const char * src
vtkStandardNewMacro(vtkPlusPhilips3DProbeVideoSource)
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)
unsigned long FrameNumber
vtkPlusIEEListener * Listener
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *config)
Class for providing VTK video input interface from Philips ie33 3D ultrasound probe.
PlusStatus GetFirstVideoSource(vtkPlusDataSource *&anImage)
virtual bool IsTracker() const
virtual PlusStatus InternalConnect()
virtual PlusStatus NotifyConfigured()
virtual PlusStatus Disconnect()
virtual void SetCorrectlyConfigured(bool)
void CallbackAddFrame(vtkImageData *imageData)
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_READING(deviceConfig, rootConfigElement)
virtual US_IMAGE_ORIENTATION GetInputImageOrientation()
bool StartThreadForInternalUpdates
vtkPlusPhilips3DProbeVideoSource()
PlusStatus Connect(CLIENT_POSTSCANCONVERT_CALLBACK callback, vtkPlusLogger::LogLevelType logType=vtkPlusLogger::LOG_LEVEL_ERROR)
virtual PlusStatus ModifyBufferItemFrameField(BufferItemUidType uid, const std::string &key, const std::string &value)
ChannelContainer OutputChannels
Direction vectors of rods y
int LatAndElevSmoothingIndex
void SetMachineName(const std::string &machineName)
virtual PlusStatus InternalDisconnect()
virtual ~vtkPlusPhilips3DProbeVideoSource()
Interface to a 3D positioning tool, video source, or generalized data stream.