Temporal calibration in 3D slicer

Hello,
I’m wondering if it’s possible to perform temporal calibration in 3D Slicer as well. According to the Slicer IGT tutorial, temporal calibration seems to require the use of fCal. However, using fCal for temporal calibration also involves pivot calibration. I appreciate any guidance you can provide on this matter.
Thank you.

While there is no dedicated module for temporal calibration, I find it relatively easy to do it with existing modules. Just record the data streams from two devices using maximum frame rate in the Sequences module of Slicer. While recording the data streams, do sudden direction changes with both tools at the same time. While replaying the recording frame-by-frame, you can observe the timestamps and note for yourself how much delay is there between the direction changes of the two tools. If you repeat the measurement 5-10 times, you will get a quite accurate estimation of both the delay and the variability in delay.

1 Like

Hello @ungi,

Once you estimate the delay between the data stream of the devices, what do you need to do with that information if you want to follow the ultrasound spatial calibration following the SlicerIGT tutorial available in:

https://onedrive.live.com/view.aspx?resid=7230D4DEC6058018!3712&authkey=!ACNGX3PqH0BLg74

I have already perform the temporal calibration using Clarius C3 HD3 ultrasound and NDI Polaris Spectra tracker but i don’t know how to use the delay measured in the temporal calibration for a correct spatial calibration.

Any guidance will be appreciated,

Thank you

PD: The temporal calibration has been done using fCal application and after performing the temporal calibration the device set configuration has been saved in XML format (see figure)

image

I think this page explains it all
http://perk-software.cs.queensu.ca/plus/doc/nightly/user/AlgorithmTemporalCalibration.html

You need to add that number as parameter TemporalCalibrationDurationSec.

i have already read that page but i haven’t noticed anything related to how to use the temporal calibration done in fCal in 3D slicer.

this is my config XML file. I think I defined the parameter you mentioned “TemporalCalibrationDurationSec”

<PlusConfiguration version="2.1">
  <DataCollection StartupDelaySec="2.0" >
    <DeviceSet 
      Name="PlusServer: (Jon) Temporal Calibration with NDI Polaris tracker and Clarius ultrasound device" 
      Description="No description" />
    
    <!-- NDI Polaris Tracker Device -->
    <Device
      Id="TrackerDevice"
      Type="PolarisTracker"
      ToolReferenceFrame="Tracker" >
      <DataSources>
        <DataSource Type="Tool" Id="Tool" RomFile="NdiToolDefinitions/8700339.rom"/>
        <DataSource Type="Tool" Id="Stylus" RomFile="NdiToolDefinitions/8700340.rom"/>
        <DataSource Type="Tool" Id="Reference" RomFile="NdiToolDefinitions/8700449.rom"/>
      </DataSources>
      <OutputChannels>
        <OutputChannel Id="TrackerStream" >
          <DataSource Id="Tool"/>
          <DataSource Id="Stylus"/>
          <DataSource Id="Reference"/>
        </OutputChannel>
      </OutputChannels>
    </Device>

    <!-- Clarius Ultrasound Device -->
    <Device Id="VideoDevice"
      Type="Clarius"
      IpAddress = "192.168.1.1"
      TcpPort = "5828"
      FrameWidth = "640"
      FrameHeight = "480"
      ImuEnabled = "TRUE"
      ImuOutputFileName = "ImuOutput.csv"
      WriteImagesToDisk = "FALSE">
      <DataSources>
        <DataSource Type="Video" Id="Video" PortName="B" PortUsImageOrientation="UN"/>
      </DataSources>
      <OutputChannels>
        <OutputChannel Id="VideoStream" VideoDataSourceId="Video" />
      </OutputChannels>
    </Device>


    <!-- Virtual Capture Device for NDI Polaris -->
    <Device
      Id="CaptureDevice_NDIPolaris"
      Type="VirtualCapture"
      BaseFilename="NDIRecording.igs.nrrd"
      EnableFileCompression="TRUE"
      RequestedFrameRate="20"
      EnableCapturing="TRUE"
      AdquisitionRate="20" >
      <InputChannels>
        <InputChannel Id="TrackerStream" />
      </InputChannels>
    </Device>

    <!-- Virtual Capture Device for Clarius Ultrasound -->
    <Device
      Id="CaptureDevice_Clarius"
      Type="VirtualCapture"
      BaseFilename= "ClariusRecording.igs.mha"
      EnableCapturing="TRUE"
      AdquisitionRate="20"
      RequestedFrameRate="20">
      <InputChannels>
        <InputChannel Id="VideoStream" />
      </InputChannels>
    </Device>

    <Device 
      Id="TrackedVideoDevice" 
      Type="VirtualMixer" >
      <InputChannels>
        <InputChannel Id="TrackerStream" />
        <InputChannel Id="VideoStream" />
      </InputChannels>
      <OutputChannels>
        <OutputChannel Id="TrackedVideoStream"/>
      </OutputChannels>
    </Device>

  </DataCollection>
  
  <CoordinateDefinitions>

    <!-- NDI Polaris Stylus coordinate transformation -->
    <Transform From="StylusTip" To="Stylus"
      Matrix="
        1	0	0.000203823	0.0180449
        3.31529e-09	-1	-1.62655e-05	-0.00144002
        0.000203823	1.62655e-05	-1	-88.5321
        0	0	0	1"
       Error="0.554951" Date="012617_105449" />

    <!-- Clarius Ultrasound Image coordinate transformation -->
    <Transform From="Image" To="Reference"
      Matrix="
      0.2 0.0 0.0 0.0
      0.0 0.2 0.0 0.0
      0.0 0.0 0.2 0.0
      0 0 0 1" />

    <Transform From="Image" To="TransducerOriginPixel"
    Matrix="1 0 0 -410
            0 1 0 5
            0 0 1 0
            0 0 0 1"
    Date="2011.12.06 17:57:00" Error="0.0" />
  </CoordinateDefinitions>

  <PlusOpenIGTLinkServer
    MaxNumberOfIgtlMessagesToSend="1"
    MaxTimeSpentWithProcessingMs="50"
    ListeningPort="64010"
    SendValidTransformsOnly="false"
    OutputChannelId="VideoStream" >
    <DefaultClientInfo>
      <MessageTypes>
        <Message Type="IMAGE" />
        <Message Type="TRANSFORM" />
      </MessageTypes>
      <ImageNames>
        <Image Name="Image" EmbeddedTransformToFrame="Reference" />
      </ImageNames>
      <TransformNames>
        <Transform Name="ImageToReference" />
      </TransformNames>
    </DefaultClientInfo>
  </PlusOpenIGTLinkServer>

    <!-- NDI Polaris PlusOpenIGTLinkServer config -->
    <PlusOpenIGTLinkServer 
    MaxNumberOfIgtlMessagesToSend="1"
    MaxTimeSpentWithProcessingMs="50"
    ListeningPort="18944"
    SendValidTransformsOnly="true"
    OutputChannelId="TrackerStream">
    <DefaultClientInfo>
      <MessageTypes>
        <Message Type="TRANSFORM" />
      </MessageTypes>
      <TransformNames>
        <Transform Name="StylusTipToReference" />
        <Transform Name="ToolToReference" />
        <Transform Name="ToolToTracker" />
        <Transform Name="StylusToTracker" />
        <Transform Name="ReferenceToTracker" />
      </TransformNames>
    </DefaultClientInfo>
  </PlusOpenIGTLinkServer>

  <fCal
  NumberOfCalibrationImagesToAcquire="200"
  NumberOfValidationImagesToAcquire="100"
  NumberOfStylusCalibrationPointsToAcquire="200"
  RecordingIntervalMs="100"
  MaxTimeSpentWithProcessingMs="70"
  TemporalCalibrationDurationSec="10"
  FixedChannelId="VideoStream" 
  FixedSourceId="Video"
  MovingChannelId="TrackerStream"
  MovingSourceId="ReferenceToTracker"
  DefaultSelectedChannelId="TrackedVideoStream" 
  FreeHandStartupDelaySec="3" />

  <vtkTemporalCalibrationAlgo
  ClipRectangleOrigin="27 27" 
  ClipRectangleSize="766 562" />

</PlusConfiguration>

I may be wrong and that parameter is to determine the length of the recording that is used for temporal calibration. Need to see the code at this point.

Taking another look I think it is this parameter of each device that you need to set after finding out the temporal lag of the devices

See also here:
http://perk-software.cs.queensu.ca/plus/doc/nightly/user/Configuration.html

" LocalTimeOffsetSec . This value allows for compensating time lag of the data acquisition of the device. The value is typically determined by temporal calibration. Global time (common for all devices in the process) is computed from the device’s local time (timestamps provided by the device) as: GlobalTime = LocalTime + LocalTimeOffset. Therefore, if local time is the time when the process receives the data from a device and it takes 0.5 sec for the device to acquire data and send to the process then the LocalTimeOffsetSec value will be -0.5. Optional. Default value is 0 sec."

1 Like