US Simulation using Hybrid Ultrasound Simulation algorithm

Hello ImFusion team,

I’m currently trying to create several US simulations with different probe geometry, to then have both image and pose details for INR experiments. I saw that the results from “Hybrid US simulation algorithm” are good, but got the following doubts while setting up the the pipeline:

  1. Is there a way to create custom US_sweep files with different geometries (similar to the public example) file to then re-use them on different label files? For example, to simulate the organ scan from different view angles / axis.

I though about drawing custom transducer and direction splines, export them as .imf and extract the trajectory details with the python SDK (or splines if possible - not sure if applicable). Can I please confirm if this is valid or if there are other ways or code around it?

  1. In the US Sweep doc, there is this note “pose matrices of Ultrasound Sweep images, are expressed from image to world coordinate system”. What is the explicit physical layout of the local 2D x_img coordinate system? For example, do pixel columns correspond to the lateral direction (+X) and rows to the axial depth direction (+Y)?

Thank you very much for your work and support!

Hi Abdelrahman,

Yes it is possible to create custom US Sweeps. You can do that using the suite:

  1. Right click on the sweep and open Tracking; Tracking Properties. On the new controller you’ll be able to change the registration and calibration matrices of the selected suite.
  2. Right click on the sweep and open Ultrasound; Frame Geometry Properties. There you will be able to change the frame geometry for the given sweep between standard geometries, as well as changing the parameters for them.
  3. You can then save this sweep and store it for later use elsewhere.

If you want to create sweeps on a more programmatical way, you might be interested in using the Python SDK, here is a quick example of a sweep rotating around the z axis with a circular frame geometry:

num_frames: int = 36,
image_size: tuple[int, int] = (256, 256),
short_radius_mm: float = 5.0,
depth_mm: float = 40.0,
start: tuple[float, float, float] = (0.0, 0.0, 0.0),
end: tuple[float, float, float] = (1.0, 1.0, 0.0),
total_rotation_deg: float = 360.0,

width, height = image_size
long_radius_mm = short_radius_mm + depth_mm

img_desc = imfusion.ImageDescriptor(imfusion.PixelType.UBYTE, width, height)
img_desc.spacing = np.array([1.0, 1.0, 1.0], dtype=np.float64)
img_desc.is_metric = True

# For circular geometry, offset is the center of the annulus.
frame_geometry = us.FrameGeometryCircular(
    coord_sys=us.CoordinateSystem.IMAGE,
    short_radius=short_radius_mm,
    long_radius=long_radius_mm,
    depth=depth_mm,
    offset=(width / 2.0, height / 2.0),
    img_desc=img_desc,
)

sweep = us.UltrasoundSweep()
sweep.components.frame_geometry_metadata.frame_geometry = frame_geometry

tracking = imfusion.TrackingSequence("synthetic")
start_vec = np.asarray(start, dtype=np.float64)
end_vec = np.asarray(end, dtype=np.float64)
total_rotation_rad = float(np.deg2rad(total_rotation_deg))

frame_template = np.zeros((height, width, 1), dtype=np.uint8)
denom = max(num_frames - 1, 1)

for index in range(num_frames):
    t = index / denom
    pose = frame_pose(t, start_vec, end_vec, total_rotation_rad)
    sweep.add(imfusion.SharedImage(frame_template.copy()))
    tracking.add(pose)

sweep.add_tracking(tracking)
sweep.tracking_used = 0
sweep.use_timestamps = False

Regarding the coordinate systems, you can take a look at the C++ SDK documentation, which is shared by Python, but you are correct in your understanding already.

Additionally, please look at this forum entry where another user created a spline via manipulation of a workspace file, which I think might be also relevant to your use case.

Best regards,