7 #include "PlusConfigure.h" 10 #include "vtkImageData.h" 11 #include "vtkObjectFactory.h" 12 #include "vtkImageImport.h" 17 #include "vtkPlusUSImagingParameters.h" 23 #include "IntersonCxxImagingScan2DClass.h" 24 #include "IntersonCxxControlsHWControls.h" 25 #include "IntersonCxxIntersonClass.h" 26 #include "IntersonCxxImagingScanConverter.h" 37 struct BmodeCallbackClientData
41 struct RfCallbackClientData
47 void vtkPlusIntersonSDKCxxVideoSource::NewBmodeImageCallback( BmodePixelType * buffer,
void * clientData )
51 LOG_ERROR(
"No actual frame data received");
55 BmodeCallbackClientData * callbackClientData = static_cast< BmodeCallbackClientData * >( clientData );
58 if( activeIntersonDevice != NULL )
60 activeIntersonDevice->AddBmodeFrameToBuffer( buffer, clientData );
64 LOG_ERROR(
"vtkPlusIntersonSDKCxxVideoSource B-mode callback but the ActiveIntersonDevice is NULL. Disconnect between the device and SDK.");
70 void vtkPlusIntersonSDKCxxVideoSource::NewRfImageCallback( RfPixelType * buffer,
void * clientData )
74 LOG_ERROR(
"No actual frame data received");
78 RfCallbackClientData * callbackClientData = static_cast< RfCallbackClientData * >( clientData );
81 if( activeIntersonDevice != NULL )
83 activeIntersonDevice->AddRfFrameToBuffer( buffer, clientData );
87 LOG_ERROR(
"vtkPlusIntersonSDKCxxVideoSource B-mode callback but the ActiveIntersonDevice is NULL. Disconnect between the device and SDK.");
92 class vtkPlusIntersonSDKCxxVideoSource::vtkInternal
105 this->BmodeClientData.ActiveIntersonDevice = this->External;
106 this->RfClientData.ActiveIntersonDevice = this->External;
108 this->BModeBufferToVtkImage = vtkImageImport::New();
109 this->BModeBufferToVtkImage->SetDataScalarType( VTK_UNSIGNED_CHAR );
110 this->BModeBufferToVtkImage->SetDataExtent( 0, Scan2DClassType::MAX_SAMPLES - 1, 0, Scan2DClassType::MAX_VECTORS - 1, 0, 0 );
111 this->BModeBufferToVtkImage->SetWholeExtent( 0, Scan2DClassType::MAX_SAMPLES - 1, 0, Scan2DClassType::MAX_VECTORS - 1, 0, 0 );
113 this->RfBufferToVtkImage = vtkImageImport::New();
114 this->RfBufferToVtkImage->SetDataScalarType( VTK_SHORT );
115 this->RfBufferToVtkImage->SetDataExtent( 0, Scan2DClassType::MAX_RFSAMPLES - 1, 0, Scan2DClassType::MAX_VECTORS - 1, 0, 0 );
116 this->RfBufferToVtkImage->SetWholeExtent( 0, Scan2DClassType::MAX_RFSAMPLES - 1, 0, Scan2DClassType::MAX_VECTORS - 1, 0, 0 );
120 vtkPlusIntersonSDKCxxVideoSource::vtkInternal::~vtkInternal()
122 this->External = NULL;
125 delete IntersonClass;
127 this->BModeBufferToVtkImage->Delete();
128 this->RfBufferToVtkImage->Delete();
131 std::string GetSdkVersion()
133 return this->IntersonClass->Version();
138 return this->HWControls;
143 return this->Scan2DClass;
146 vtkImageData * ConvertBModeBufferToVtkImage(
unsigned char * pixelData )
148 this->BModeBufferToVtkImage->SetImportVoidPointer( pixelData );
149 this->BModeBufferToVtkImage->Update();
150 return this->BModeBufferToVtkImage->GetOutput();
153 vtkImageData * ConvertRfBufferToVtkImage(
short * pixelData )
155 this->RfBufferToVtkImage->SetImportVoidPointer( pixelData );
156 this->RfBufferToVtkImage->Update();
157 return this->RfBufferToVtkImage->GetOutput();
160 void EnableBModeCallback()
162 this->Scan2DClass->SetNewBmodeImageCallback( &vtkPlusIntersonSDKCxxVideoSource::NewBmodeImageCallback,
163 &(this->BmodeClientData) );
166 void DisableBModeCallback()
168 this->Scan2DClass->SetNewBmodeImageCallback( NULL, NULL );
171 void EnableRfCallback()
173 this->Scan2DClass->SetNewRFImageCallback( &vtkPlusIntersonSDKCxxVideoSource::NewRfImageCallback,
174 &(this->RfClientData) );
177 void DisableRfCallback()
179 this->Scan2DClass->SetNewRFImageCallback( NULL, NULL );
191 if( !(*channelIt)->HasVideoSource() )
193 LOG_ERROR(
"Output channel does not have VideoSource" );
197 (*channelIt)->GetVideoSource( channelSource );
198 if( channelSource ==
source )
212 BmodeCallbackClientData BmodeClientData;
213 RfCallbackClientData RfClientData;
215 vtkImageImport * BModeBufferToVtkImage;
216 vtkImageImport * RfBufferToVtkImage;
225 this->
Internal =
new vtkInternal(
this);
252 os << indent <<
"Pulse voltage: " << this->
PulseVoltage <<
"\n";
253 os << indent <<
"RF decimation: " << this->
RfDecimation <<
"\n";
259 LOG_TRACE(
"vtkPlusIntersonSDKCxxVideoSource::InternalConnect" );
263 typedef HWControlsType::FoundProbesType FoundProbesType;
264 FoundProbesType foundProbes;
265 hwControls->FindAllProbes( foundProbes );
266 if( foundProbes.empty() )
268 LOG_ERROR(
"Interson SDK Cxx could not find the probe." );
271 if( foundProbes.size() > 1 )
273 LOG_WARNING(
"Multiple Interson probes are attached, using the first one");
275 hwControls->FindMyProbe( 0 );
276 const unsigned int probeId = hwControls->GetProbeID();
277 LOG_DEBUG(
"Found probe ID: " << probeId );
280 LOG_ERROR(
"Interson SDK Cxx could not find the probe." );
291 if( !hwControls->SendHighVoltage( this->PulseVoltage ) )
293 LOG_ERROR(
"Could not set the pulse voltage." );
296 if( !hwControls->EnableHighVoltage() )
298 LOG_ERROR(
"Could not enable high voltage." );
302 double dynamicRangeDb = -1;
310 hwControls->DisableHardButton();
313 std::vector<vtkPlusDataSource *> rfSources;
317 if( !rfSources.empty() )
319 scan2D->SetRFData(
true );
323 scan2D->SetRFData(
false );
326 LOG_DEBUG(
"Interson SDK version " << this->
Internal->GetSdkVersion() <<
327 ", USB probe FPGA version " << hwControls->ReadFPGAVersion() );
331 const bool upDown =
false;
332 const bool leftRight =
false;
333 const int width = 1000;
335 const int scanConvertDepth = 10;
336 typedef IntersonCxx::Imaging::ScanConverter ScanConverterType;
337 ScanConverterType scanConverter;
338 ScanConverterType::ScanConverterError converterError =
339 scanConverter.HardInitScanConverter( scanConvertDepth,
345 std::vector<vtkPlusDataSource *> bmodeSources;
348 if( !rfSources.empty() )
351 this->
Internal->DisableBModeCallback();
355 hwControls->EnableRFDecimator();
359 hwControls->DisableRFDecimator();
369 LOG_ERROR(
"Could not find channel for source" );
374 source->SetPixelType( VTK_SHORT );
375 source->SetImageType( US_IMG_RF_REAL );
376 source->SetOutputImageOrientation( US_IMG_ORIENT_FM );
377 source->SetInputFrameSize( Scan2DClassType::MAX_RFSAMPLES,
378 Scan2DClassType::MAX_VECTORS,
380 LOG_INFO(
"RF Pixel type: " << vtkImageScalarTypeNameMacro(
source->GetPixelType() )
381 <<
", device image orientation: " 382 << igsioCommon::GetStringFromUsImageOrientation(
source->GetInputImageOrientation() )
383 <<
", buffer image orientation: " 384 << igsioCommon::GetStringFromUsImageOrientation(
source->GetOutputImageOrientation() ));
387 if( !bmodeSources.empty() )
389 LOG_INFO(
"BMode souces are not empty!!");
394 LOG_ERROR(
"Could not find channel for source" );
400 source->SetPixelType( VTK_UNSIGNED_CHAR );
401 source->SetImageType( US_IMG_BRIGHTNESS ) ;
403 if( rfProcessor != NULL )
405 channel->SetSaveRfProcessingParameters(
true);
406 source->SetOutputImageOrientation( US_IMG_ORIENT_MF );
408 if( scanConverter != NULL )
412 source->SetInputFrameSize( outputExtent[1] - outputExtent[0] + 1,
413 outputExtent[3] - outputExtent[2] + 1,
419 source->SetOutputImageOrientation( US_IMG_ORIENT_FM );
420 source->SetInputFrameSize( Scan2DClassType::MAX_RFSAMPLES,
421 Scan2DClassType::MAX_VECTORS,
424 LOG_INFO(
"Pixel type: " << vtkImageScalarTypeNameMacro(
source->GetPixelType() )
425 <<
", device image orientation: " 426 << igsioCommon::GetStringFromUsImageOrientation(
source->GetInputImageOrientation() )
427 <<
", buffer image orientation: " 428 << igsioCommon::GetStringFromUsImageOrientation(
source->GetOutputImageOrientation() ));
431 else if( !bmodeSources.empty() )
433 this->
Internal->EnableBModeCallback();
434 this->
Internal->DisableRfCallback();
436 source = bmodeSources[0];
439 source->SetPixelType( VTK_UNSIGNED_CHAR );
440 source->SetImageType( US_IMG_BRIGHTNESS );
445 LOG_ERROR(
"Could not find channel for source" );
451 if( rfProcessor != NULL )
454 if( scanConverter != NULL )
456 channel->SetSaveRfProcessingParameters(
true);
457 source->SetOutputImageOrientation( US_IMG_ORIENT_MF );
460 source->SetInputFrameSize( outputExtent[1] - outputExtent[0] + 1,
461 outputExtent[3] - outputExtent[2] + 1,
466 LOG_ERROR(
"Did not find expected scan converter parameters." );
472 source->SetOutputImageOrientation( US_IMG_ORIENT_MF );
473 source->SetInputFrameSize( Scan2DClassType::MAX_SAMPLES,
474 Scan2DClassType::MAX_VECTORS,
479 LOG_INFO(
"BMode Pixel type: " << vtkImageScalarTypeNameMacro(
source->GetPixelType() )
480 <<
", device image orientation: " 481 << igsioCommon::GetStringFromUsImageOrientation(
source->GetInputImageOrientation() )
482 <<
", buffer image orientation: " 483 << igsioCommon::GetStringFromUsImageOrientation(
source->GetOutputImageOrientation() ));
487 LOG_ERROR(
"Expected an RF or BMode port not found" );
498 LOG_DEBUG(
"Disconnect from Interson");
501 hwControls->DisableHighVoltage();
517 if( !hwControls->StartMotor() )
519 LOG_ERROR(
"Could not start motor." );
523 std::vector<vtkPlusDataSource *> bmodeSources;
524 std::vector<vtkPlusDataSource *> rfSources;
528 if( !rfSources.empty() )
530 scan2D->StartRFReadScan();
532 else if( !bmodeSources.empty() )
534 scan2D->StartReadScan();
538 if( !rfSources.empty() && !hwControls->StartRFmode() )
540 LOG_ERROR(
"Could not start RF collection." );
543 else if( !bmodeSources.empty() && !hwControls->StartBmode() )
545 LOG_ERROR(
"Could not start B-mode collection." );
557 if( !hwControls->StopAcquisition() )
559 LOG_ERROR(
"Could not stop acquisition." );
564 scan2D->StopReadScan();
566 scan2D->DisposeScan();
567 if( !hwControls->StopMotor() )
569 LOG_ERROR(
"Could not stop motor." );
590 LOG_TRACE(
"vtkPlusIntersonSDKCxxVideoSource::ReadConfiguration");
591 if ( config == NULL )
593 LOG_ERROR(
"Unable to configure Interson video source! (XML data element is NULL)");
600 if (deviceConfig == NULL)
602 LOG_ERROR(
"Unable to find ImageAcquisition element in configuration XML structure!");
606 double dynRange = -1;
607 if ( deviceConfig->GetScalarAttribute(
"DynRangeDb", dynRange))
613 if ( deviceConfig->GetScalarAttribute(
"FrequencyMhz",
frequency))
618 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
int,
PulseVoltage, deviceConfig);
619 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
int,
RfDecimation, deviceConfig);
628 deviceConfig->SetIntAttribute(
"PulseVoltage", this->
GetPulseVoltage());
629 deviceConfig->SetIntAttribute(
"RfDecimation", this->
RfDecimation);
640 LOG_WARNING(
"vtkPlusIntersonSDKCxxVideoSource is expecting at most two output channels and there are " << this->
OutputChannels.size() <<
" channels.");
645 LOG_ERROR(
"No output channels defined for vtkPlusIntersonSDKCxxVideoSource. Cannot proceed." );
656 return this->
Internal->GetSdkVersion();
686 int frequency = static_cast< int >( freq * 1e6 );
689 HWControlsType::FrequenciesType supportedFrequencies;
690 hwControls->GetFrequency( supportedFrequencies );
692 unsigned int frequencyIndex = 0;
693 if(
frequency <= supportedFrequencies[0] )
697 const size_t numSupportedFrequencies = supportedFrequencies.size();
698 if(
frequency >= supportedFrequencies[numSupportedFrequencies - 1] )
700 frequencyIndex = numSupportedFrequencies - 1;
702 for(
size_t ii = 1; ii < numSupportedFrequencies - 1; ++ii )
704 const int lower = supportedFrequencies[ii - 1] +
705 ( supportedFrequencies[ii] - supportedFrequencies[ii - 1] ) / 2;
708 frequencyIndex = ii - 1;
711 const int upper = supportedFrequencies[ii] +
712 ( supportedFrequencies[ii + 1] - supportedFrequencies[ii] ) / 2;
718 frequencyIndex = ii + 1;
720 frequency = supportedFrequencies[frequencyIndex];
721 LOG_DEBUG(
"Current frequency is " <<
frequency / 1.0e6 );
723 if( !hwControls->SetFrequency(
frequency ) )
725 LOG_ERROR(
"Could not set the frequency." );
737 unsigned char usedGain = 100;
738 if( dynRangeDb > 0.0 )
740 usedGain = static_cast< unsigned char >( 255 * dynRangeDb );
743 if( !hwControls->SendDynamic( usedGain ) )
745 LOG_ERROR(
"Could not set dynamic gain." );
752 PlusStatus vtkPlusIntersonSDKCxxVideoSource::AddBmodeFrameToBuffer( BmodePixelType * buffer,
void * clientData )
761 if( hwControls->ReadHardButton() )
766 vtkImageData * bufferVtkImageData = NULL;
769 std::vector<vtkPlusDataSource *> sources;
772 if( !sources.empty() )
778 LOG_ERROR(
"Expected Bmode port not found" );
785 if( rfProcessor != NULL )
794 if( scanConverter != NULL )
797 scanConverter->Modified();
798 scanConverter->Update();
799 bufferVtkImageData = scanConverter->
GetOutput();
804 bufferVtkImageData = this->
Internal->ConvertBModeBufferToVtkImage( buffer );
808 source->GetInputImageOrientation(),
818 PlusStatus vtkPlusIntersonSDKCxxVideoSource::AddRfFrameToBuffer( RfPixelType * buffer,
void * clientData )
827 if( hwControls->ReadHardButton() )
834 std::vector<vtkPlusDataSource *> rfSources;
837 if( !rfSources.empty() )
843 LOG_ERROR(
"Expected RF port not found" );
849 vtkImageData * rfBufferVtkImageData = this->
Internal->ConvertRfBufferToVtkImage( buffer );
850 if(
source->AddItem( rfBufferVtkImageData,
851 source->GetInputImageOrientation(),
855 LOG_ERROR(
"Failed to add RF frame to buffer" );
859 std::vector<vtkPlusDataSource *> bmodeSources;
861 if( !bmodeSources.empty() )
866 if( rfProcessor != NULL )
868 rfProcessor->
SetRfFrame( rfBufferVtkImageData,
872 vtkImageData * bmodeBufferVtkImageData = NULL;
873 if( scanConverter != NULL )
881 if(
source->AddItem( bmodeBufferVtkImageData,
882 source->GetInputImageOrientation(),
886 LOG_ERROR(
"Failed to add BMode frame to buffer." );
892 LOG_ERROR(
"Expected RfProcessor not found." );
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
static const std::string RFMODE_PORT_NAME
virtual vtkPlusRfToBrightnessConvert * GetRfToBrightnessConverter()
virtual PlusStatus InternalStopRecording()
PhidgetRCServo_Voltage voltage
IntersonArrayCxx::Controls::HWControls HWControlsType
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_WRITING(deviceConfig, rootConfigElement)
vtkPlusUsImagingParameters * ImagingParameters
static const std::string BMODE_PORT_NAME
virtual vtkPlusUsScanConvert * GetScanConverter()
virtual PlusStatus InternalUpdate()
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *config)
bool RequirePortNameInDeviceSetConfiguration
bool RequireImageOrientationInConfiguration
virtual vtkImageData * GetBrightnessScanConvertedImage()
PlusStatus GetVideoSourcesByPortName(const char *aPortName, std::vector< vtkPlusDataSource * > &sources)
virtual PlusStatus SetRfFrame(vtkImageData *rfFrame, US_IMAGE_TYPE imageType)
Class for acquiring ultrasound images from Interson USB ultrasound systems with C++ Wrapped SDK.
vtkStandardNewMacro(vtkPlusIntersonSDKCxxVideoSource)
virtual PlusStatus Disconnect()
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *)
unsigned long FrameNumber
vtkPlusIntersonSDKCxxVideoSource()
virtual std::string GetSdkVersion()
virtual PlusStatus InternalStartRecording()
IntersonCxx::Controls::HWControls HWControlsType
PlusStatus SetDynRangeDb(double dynRangeDb)
vtkXMLDataElement * FindThisDeviceElement(vtkXMLDataElement *rootXMLElement)
ChannelContainer::const_iterator ChannelContainerConstIterator
virtual PlusStatus NotifyConfigured()
virtual PlusStatus StopRecording()
PlusStatus SetPulseVoltage(unsigned char voltage)
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *config)
IntersonArrayCxx::IntersonClass IntersonClassType
PlusStatus GetDynRangeDb(double &aDynRangeDb) const
static vtkPlusUsImagingParameters * New()
IntersonCxx::IntersonClass IntersonClassType
PhidgetLCD_Font int * width
PlusStatus SetDynRangeDb(double aDynRangeDb)
virtual PlusStatus InternalDisconnect()
virtual PlusStatus InternalConnect()
virtual int * GetOutputImageExtent()
IntersonCxx::Imaging::Scan2DClass Scan2DClassType
Convenience class to combine multiple algorithms to compute a displayable B-mode frame from RF data.
bool StartThreadForInternalUpdates
PhidgetLCD_Font int int * height
Contains an optional timestamped circular buffer containing the video images and a number of timestam...
PlusStatus SetFrequencyMhz(double aFrequencyMhz)
PlusStatus SetProbeFrequencyMhz(double aFreq)
virtual void SetInputData(vtkDataObject *input)
ChannelContainer OutputChannels
PlusStatus GetFrequencyMhz(double &aFrequencyMhz) const
This is a base class for defining a common scan conversion algorithm interface for all kinds of probe...
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
~vtkPlusIntersonSDKCxxVideoSource()
virtual unsigned char GetPulseVoltage()
virtual vtkImageData * GetOutput()=0
PlusStatus SetRfDecimation(int enableDecimation)
unsigned char PulseVoltage
virtual PlusStatus InternalUpdate()
virtual vtkImageData * GetBrightnessConvertedImage()
Interface to a 3D positioning tool, video source, or generalized data stream.