Plus applications user manual  2.7.0.3de27e5
Software library for tracked ultrasound image acquisition, calibration, and processing.
Volume reconstruction algorithm

This algorithm reconstructs a 3D volume from a set of 2D image slices.

The reconstructor takes as input a set of tracked ultrasound slices. A rectangular or fan-shaped clipping region may be applied on each slice to make sure only valid image regions are used for reconstruction. Angle range of fan-shaped clipping region may be adjusted automatically based on image contents to exclude areas in the image that remain blank because lack of acoustic coupling between the transducer and the scanned surface.

At the beginning of the reconstruction, a 3D voxel array is constructed (location, size, and resolution is specified in the configuration file or detected automatically from the location of the image slices). Then, each pixels of slice is inserted into a volume (distribution step). Each pixel value is inserted either into the spatially nearest single voxel or into the spatially nearest set of 8 voxels according to options specified in the config file.

Once all the available frames have been inserted, an optional hole-filling step may be performed. An algorithm is used to attempt to fill each voxel that has not been assigned any intensity value in the distribution step.

Troubleshooting volume reconstruction

Configuration settings

Clipping

Images slices often contain irrelevant parts for volume reconstruction, e.g., dark or black regions at the image boundary or out of the image fan. To remove these image regions a rectangular and fan-shaped clipping areas can be defined.

Clipping rectangle must be always defined. Clipping fan is optional and it is applied in addition to the clipping rectangle: all pixels that are outside the clipping rectangle or outisde the clipping fan will be ignored in volume reconstruction.

Clipping rectangle and clipping fan are always defined in the MF coordinate system. If the UltrasoundImageOrientation field in the stored sequence file is not MF and the file is loaded into a generic software that ignores the UltrasoundImageOrientation field (such as ImageJ, 3D Slicer, Paraview) then the XY positions and orientations shown in the generic software has to be transformed. For example, if the image size is 640x480 pixels and UltrasoundImageOrientation=MN and the FanOrigin appears in the (320,440) position in ImageJ then the FanOriginPixel in the XML config file shall be (320,40).

AlgorithmVolumeReconstructionLinearRoi.png
AlgorithmVolumeReconstructionCurvilinearRoi.png

Compounding mode

VolumeReconCompoundingMean.png
VolumeReconCompoundingMax.png
VolumeReconCompoundingLatest.png

Examples

Example configuration file PlusDeviceSet_Server_Sim_NwirePhantom.xml

<PlusConfiguration version="2.1">
<DataCollection StartupDelaySec="1.0" >
<DeviceSet
Name="PlusServer: Replay fCal phantom scan with Ultrasonix US (L14-5 probe) + Ascension3DG tracker (Probe, Reference, Stylus)"
Description="Free-hand probe motion, imaging 3 NWires, after spatial calibration. OpenIGTLink broadcasting through PlusServer of image and tool tracking data." />
<Device
Id="TrackedVideoDevice"
Type="SavedDataSource"
SequenceFile="fCal_Test_Calibration_3NWires.igs.mha"
UseData="IMAGE_AND_TRANSFORM"
UseOriginalTimestamps="TRUE"
RepeatEnabled="TRUE" >
<DataSources>
<DataSource Type="Video" Id="Video" />
</DataSources>
<OutputChannels>
<OutputChannel Id="TrackedVideoStream" VideoDataSourceId="Video" />
</OutputChannels>
</Device>
<Device
Id="CaptureDevice"
Type="VirtualCapture"
BaseFilename="RecordingTest.igs.mha"
EnableCapturingOnStart="FALSE" >
<InputChannels>
<InputChannel Id="TrackedVideoStream" />
</InputChannels>
</Device>
<Device
Id="VolumeReconstructorDevice"
Type="VirtualVolumeReconstructor"
OutputVolDeviceName="RecVol_Reference">
<InputChannels>
<InputChannel Id="TrackedVideoStream" />
</InputChannels>
<VolumeReconstruction
ImageCoordinateFrame="Image" ReferenceCoordinateFrame="Reference"
Interpolation="LINEAR" Optimization="NONE" CompoundingMode="MEAN" FillHoles="OFF" NumberOfThreads="2"
ClipRectangleOrigin="0 0" ClipRectangleSize="820 616"
OutputOrigin="-15 -15 30" OutputExtent="0 300 0 300 0 300" OutputSpacing="0.15 0.15 0.15" />
</Device>
</DataCollection>
<PlusOpenIGTLinkServer
MaxNumberOfIgtlMessagesToSend="1"
MaxTimeSpentWithProcessingMs="50"
ListeningPort="18944"
SendValidTransformsOnly="true"
OutputChannelId="TrackedVideoStream" >
<DefaultClientInfo>
<MessageTypes>
<Message Type="IMAGE" />
<Message Type="TRANSFORM" />
</MessageTypes>
<TransformNames>
<Transform Name="ProbeToTracker" />
<Transform Name="ReferenceToTracker" />
<Transform Name="ProbeToReference" />
</TransformNames>
<ImageNames>
<Image Name="Image" EmbeddedTransformToFrame="Reference" />
</ImageNames>
</DefaultClientInfo>
</PlusOpenIGTLinkServer>
<CoordinateDefinitions>
<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" />
<Transform From="Phantom" To="Reference"
Matrix="
0.00898765 -0.0136951 -0.999866 9.59137
0.0246163 -0.9996 0.0139127 36.0012
-0.999657 -0.024738 -0.00864693 87.8909
0 0 0 1"
Error="0.404711" Date="012712_152104" />
<Transform From="StylusTip" To="Stylus"
Matrix="
1 0 0 203.772
0 1 0 -12.283
0 0 1 1.17469
0 0 0 1"
Error="0.582721" Date="012712_152030" />
<Transform From="Image" To="Probe"
Matrix="
0 0.08 0 11
-0.08 0 0 50
0 0 0.08 0
0 0 0 1"
Error="0.582721" Date="012712_152030" />
</CoordinateDefinitions>
</PlusConfiguration>

Example configuration file PlusDeviceSet_VolumeReconstructionOnly_SonixRP_TRUS_D70mm_NN_LATE.xml

<PlusConfiguration version="2.1">
<!--
This configuration is for volume reconstruction from US image slices recorded with
Sonix RP machine, TRUS probe.
Image geometry: depth = 70mm, zoom = 100%.
-->
<CoordinateDefinitions>
<Transform From="Image" To="Probe"
Matrix="-0.00157821 0.0785919 -0.00803285 15.3978
-0.0839128 0.00372697 0.0153803 49.5705
0.0159024 0.00714276 0.0803604 -8.63446
0 0 0 1"
Error="1.68149" Date="022312_110631"
/>
<Transform From="Phantom" To="Reference"
Matrix="-0.0263954 0.0123051 -0.999576 11.9823
0.0167829 0.999789 0.0118645 -37.1153
0.999511 -0.0164626 -0.0265963 -85.3543
0 0 0 1"
Error="1.87619" Date="022312_110322"
/>
</CoordinateDefinitions>
<VolumeReconstruction OutputSpacing="0.5 0.5 0.5"
ClipRectangleOrigin="192 16" ClipRectangleSize="420 580"
FanAnglesDeg="-45 45" FanOriginPixel="380 20" FanRadiusStartPixel="120" FanRadiusStopPixel="360"
Interpolation="NEAREST_NEIGHBOR" Optimization="FULL"
CompoundingMode="LATEST" FillHoles="OFF" NumberOfThreads="1" />
</PlusConfiguration>

Example configuration file PlusDeviceSet_VolumeReconstructionOnly_SpinePhantom_NN_MAXI.xml

<PlusConfiguration version="2.1">
<CoordinateDefinitions>
<Transform From="Image" To="Probe"
Matrix="-0.00157821 0.0785919 -0.00803285 15.3978
-0.0839128 0.00372697 0.0153803 49.5705
0.0159024 0.00714276 0.0803604 -8.63446
0 0 0 1"
Error="1.68149" Date="022312_110631"
/>
<Transform From="Phantom" To="Reference"
Matrix="-0.0263954 0.0123051 -0.999576 11.9823
0.0167829 0.999789 0.0118645 -37.1153
0.999511 -0.0164626 -0.0265963 -85.3543
0 0 0 1"
Error="1.87619" Date="022312_110322"
/>
</CoordinateDefinitions>
<VolumeReconstruction OutputSpacing="0.5 0.5 0.5"
ClipRectangleOrigin="0 0" ClipRectangleSize="820 616"
Interpolation="NEAREST_NEIGHBOR" Optimization="FULL"
CompoundingMode="MAXIMUM" FillHoles="ON" NumberOfThreads="1">
<HoleFilling>
<HoleFillingElement
Type="STICK"
StickLengthLimit="9"
NumberOfSticksToUse="1" />
</HoleFilling>
</VolumeReconstruction>
</PlusConfiguration>

Example configuration file for Acquisition server (PlusDeviceSet_Server_Sim_NwirePhantomTrackedFrameAcquisition.xml)

<PlusConfiguration version="2.1">
<DataCollection StartupDelaySec="1.0" >
<DeviceSet
Name="PlusServer: TRACKEDFRAME acquisition server. fCal phantom scan with Ultrasonix US (L14-5 probe) + Ascension3DG tracker (Probe, Reference, Stylus)"
Description="Free-hand probe motion, imaging 3 NWires, after spatial calibration. OpenIGTLink broadcasting of TRACKEDFRAME message through PlusServer." />
<Device
Id="TrackedVideoDevice"
Type="SavedDataSource"
SequenceFile="fCal_Test_Calibration_3NWires.igs.mha"
UseData="IMAGE_AND_TRANSFORM"
UseOriginalTimestamps="TRUE"
RepeatEnabled="TRUE" >
<DataSources>
<DataSource Type="Video" Id="Video" />
</DataSources>
<OutputChannels>
<OutputChannel Id="TrackedVideoStream" VideoDataSourceId="Video" />
</OutputChannels>
</Device>
</DataCollection>
<PlusOpenIGTLinkServer
MaxNumberOfIgtlMessagesToSend="1"
MaxTimeSpentWithProcessingMs="50"
ListeningPort="18000"
SendValidTransformsOnly="true"
OutputChannelId="TrackedVideoStream" >
<DefaultClientInfo>
<MessageTypes>
<Message Type="TRACKEDFRAME" />
</MessageTypes>
</DefaultClientInfo>
</PlusOpenIGTLinkServer>
</PlusConfiguration>

Example configuration file for Processing server (PlusDeviceSet_Server_Sim_NwirePhantomTrackedFrameProcessing.xml)

<PlusConfiguration version="2.1">
<DataCollection StartupDelaySec="1.0" >
<DeviceSet
Name="PlusServer: TRACKEDFRAME processing server"
Description="To be used with TRACKEDFRAME acquisition server. Receives tracked frames through OpenIGTLink and it can record sequences, reconstruct volumes, and sends IMAGE and TRANSFORM messages through OpenIGTLink." />
<Device
Id="TrackedVideoDevice"
Type="OpenIGTLinkVideo"
MessageType="TRACKEDFRAME"
ServerAddress="127.0.0.1"
ServerPort="18000"
IgtlMessageCrcCheckEnabled="false"
LocalTimeOffsetSec="0" >
<DataSources>
<DataSource Type="Video" Id="Video" PortUsImageOrientation="MF" />
</DataSources>
<OutputChannels>
<OutputChannel Id="TrackedVideoStream" VideoDataSourceId="Video" />
</OutputChannels>
</Device>
<Device
Id="CaptureDevice"
Type="VirtualCapture"
BaseFilename="RecordingTest.igs.mha"
EnableCapturingOnStart="FALSE" >
<InputChannels>
<InputChannel Id="TrackedVideoStream" />
</InputChannels>
</Device>
<Device
Id="VolumeReconstructorDevice"
Type="VirtualVolumeReconstructor"
OutputVolDeviceName="RecVol_Reference">
<InputChannels>
<InputChannel Id="TrackedVideoStream" />
</InputChannels>
<VolumeReconstruction
ImageCoordinateFrame="Image" ReferenceCoordinateFrame="Reference"
Interpolation="LINEAR" Optimization="NONE" CompoundingMode="MEAN" FillHoles="OFF" NumberOfThreads="2"
ClipRectangleOrigin="0 0" ClipRectangleSize="820 616"
OutputOrigin="-15 -15 30" OutputExtent="0 300 0 300 0 300" OutputSpacing="0.15 0.15 0.15" />
</Device>
</DataCollection>
<PlusOpenIGTLinkServer
MaxNumberOfIgtlMessagesToSend="1"
MaxTimeSpentWithProcessingMs="50"
ListeningPort="18944"
SendValidTransformsOnly="true"
OutputChannelId="TrackedVideoStream" >
<DefaultClientInfo>
<MessageTypes>
<Message Type="IMAGE" />
<Message Type="TRANSFORM" />
</MessageTypes>
<TransformNames>
<Transform Name="ProbeToTracker" />
<Transform Name="ReferenceToTracker" />
<Transform Name="ProbeToReference" />
</TransformNames>
<ImageNames>
<Image Name="Image" EmbeddedTransformToFrame="Reference" />
</ImageNames>
</DefaultClientInfo>
</PlusOpenIGTLinkServer>
<CoordinateDefinitions>
<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" />
<Transform From="Phantom" To="Reference"
Matrix="
0.00898765 -0.0136951 -0.999866 9.59137
0.0246163 -0.9996 0.0139127 36.0012
-0.999657 -0.024738 -0.00864693 87.8909
0 0 0 1"
Error="0.404711" Date="012712_152104" />
<Transform From="StylusTip" To="Stylus"
Matrix="
1 0 0 203.772
0 1 0 -12.283
0 0 1 1.17469
0 0 0 1"
Error="0.582721" Date="012712_152030" />
<Transform From="Image" To="Probe"
Matrix="
0 0.08 0 11
-0.08 0 0 50
0 0 0.08 0
0 0 0 1"
Error="0.582721" Date="012712_152030" />
</CoordinateDefinitions>
</PlusConfiguration>