# How to get the IJK coordinate of a fiducial node in 3d slicer development

**URL:** <https://discourse.slicer.org/t/how-to-get-the-ijk-coordinate-of-a-fiducial-node-in-3d-slicer-development/45362>\
**Category:** Development\
**Created:** [December 4, 2025, 2:38am UTC](https://discourse.slicer.org/t/how-to-get-the-ijk-coordinate-of-a-fiducial-node-in-3d-slicer-development/45362 "2025-12-04T02:38:25Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![zhutouzjq](https://avatars.discourse-cdn.com/v4/letter/z/8797f3/32.png) [@zhutouzjq](https://discourse.slicer.org/u/zhutouzjq)\
**Post date:** [December 4, 2025, 2:38am UTC](https://discourse.slicer.org/t/how-to-get-the-ijk-coordinate-of-a-fiducial-node-in-3d-slicer-development/45362/1 "2025-12-04T02:38:26Z")

</div>

thank the help provided by jamesobulter and cpinter, now i can successfully choose the fiducial in myself extension.

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/2/8/28d2a9002167cd5ab11adf2bca1c4418aef02caf.png)

but i fail to get the ijk coordinate of this fudicial node in my extension. i can only get the ras coordinate through the python code in class called ‘Logic‘.

def process(self,

```
            inputVolume: vtkMRMLScalarVolumeNode,

            imageThreshold: float,

            inputlowerpoint, #this is the name of qMRMLNodeCombobox by which i choose the fiducial node in 3D slicer

            inputupperpoint,

            showResult: bool = True) -> None:

    ras = vtk.vtkVector3d(0,0,0)

    inputlowerpoint.GetNthControlPointPositionWorld(0, ras)

    print('lowerpoint : IJK =’,ras)

```

after running the extension, the result in pyhton console like this:

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/f/0/f09da4ac3446f28ed098d31b7f71184087ccf0e3.png)

however, what i need is the IJK coordinate of this fudicial node. So, how can i get the IJK coordinate of a fiducial node and print in the python console?

---

<div class="post-metadata">

**Author:** ![muratmaga](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/muratmaga/32/3622_2.png) [@muratmaga](https://discourse.slicer.org/u/muratmaga)\
**Post date:** [December 4, 2025, 3:09am UTC](https://discourse.slicer.org/t/how-to-get-the-ijk-coordinate-of-a-fiducial-node-in-3d-slicer-development/45362/2 "2025-12-04T03:09:50Z")

</div>

AI is great for this type of things. I asked your question to Gemini:

“how can I get the IJK coordinates of Fiducial point that I know its world coordinates (RAS) using Slicer’s python API? Assume the coordinate is in the first control point of PointList F”

and I got

```auto
import slicer
import vtk
import numpy as np

# 1. Define the RAS coordinates (World Coordinates)
ras_point = np.array([-38.0, 24.0, -617.0, 1.0]) # Homogeneous coordinates (R, A, S, 1)

# 2. Get the reference volume node
# Replace 'YourVolumeNodeName' with the actual name or ID of your loaded volume node.
# For example, if you have the built-in MRHead:
volumeNode = slicer.util.getNode('MRHead')

if volumeNode is None:
    print("Error: Volume node not found. Please load a volume into the scene.")
else:
    # 3. Get the WorldToIJK transform matrix from the volume node
    worldToIjkMatrix = vtk.vtkMatrix4x4()
    volumeNode.GetWorldToIJKMatrix(worldToIjkMatrix)
    
    # You can convert the vtkMatrix4x4 to a numpy array for easier calculation
    worldToIjkNp = slicer.util.vtkMatrixToNumpy(worldToIjkMatrix)
    
    # 4. Calculate the IJK coordinates
    # Matrix multiplication: [I, J, K, 1] = WorldToIJK_Matrix @ [R, A, S, 1]
    ijk_point_homog = worldToIjkNp @ ras_point
    
    # The IJK coordinates are the first three components (the last is 1.0)
    # The coordinates are typically rounded to the nearest integer for voxel indices.
    ijk_point = np.round(ijk_point_homog[:3]).astype(int)
    
    print(f"RAS Coordinates (R, A, S): {ras_point[:3]}")
    print(f"IJK Coordinates (I, J, K): {ijk_point}")
    
    # Optional: Display the IJK coordinates for a specific fiducial point
    # in an existing markups node (if needed for context)
    # fiducialNode = slicer.util.getNode('F') # Replace 'F' with your markups node name
    # if fiducialNode:
    # fiducialNode.SetNthControlPointPositionWorld(0, ras_point[0], ras_point[1], ras_point[2])
    # # After setting the position, you can use the node's internal function to get IJK:
    # # ijk = [0, 0, 0]
    # # fiducialNode.GetNthControlPointPositionIJK(0, ijk)
    # # print(f"IJK from Markups node: {ijk}")

```

which seems to work.

---

<div class="post-metadata">

**Author:** ![zhutouzjq](https://avatars.discourse-cdn.com/v4/letter/z/8797f3/32.png) [@zhutouzjq](https://discourse.slicer.org/u/zhutouzjq)\
**Post date:** [December 4, 2025, 3:13am UTC](https://discourse.slicer.org/t/how-to-get-the-ijk-coordinate-of-a-fiducial-node-in-3d-slicer-development/45362/3 "2025-12-04T03:13:46Z")

</div>

thank the discussion in “[RAS to IJK conversion issues](https://discourse.slicer.org/t/ras-to-ijk-conversion-issues/41863)“. the reply by muratmaga help me a lot.

in the script repository of 3D slicer, they suggest use the follow code to transform the ras to ijk:

```auto
# Inputs
volumeNode = getNode("MRHead")
pointListNode = getNode("F")
markupsIndex = 0

# Get point coordinate in RAS
point_Ras = [0, 0, 0]
pointListNode.GetNthControlPointPositionWorld(markupsIndex, point_Ras)

# If volume node is transformed, apply that transform to get volume's RAS coordinates
transformRasToVolumeRas = vtk.vtkGeneralTransform()
slicer.vtkMRMLTransformNode.GetTransformBetweenNodes(None, volumeNode.GetParentTransformNode(), transformRasToVolumeRas)
point_VolumeRas = transformRasToVolumeRas.TransformPoint(point_Ras)

# Get voxel coordinates from physical coordinates
volumeRasToIjk = vtk.vtkMatrix4x4()
volumeNode.GetRASToIJKMatrix(volumeRasToIjk)
point_Ijk = [0, 0, 0, 1]
volumeRasToIjk.MultiplyPoint(np.append(point_VolumeRas,1.0), point_Ijk)
point_Ijk = [int(round(c)) for c in point_Ijk[0:3] ]

# Print output
print(point_Ijk)

```

but what i didn’t know is that in my code, the second line “volumeNode = getNode(“MRHead”)” should be change into “volumeNode = slicer.util.getNode(“5: CTA 0.5 CE”)“.

“MRHead“ or “5: CTA 0.5 CE“ is the name of volume which could be found here.

 ![无标题](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/7/5/757124617e2ec162960d71567ac1c32d398beb95.png)

and use the python code like this in Logic class, i can print the IJK coordinate in console now.

```
def process(self,

            inputVolume: vtkMRMLScalarVolumeNode,

            imageThreshold: float,

            inputlowerpoint,

            inputupperpoint,

            showResult: bool = True) -> None:

    """

    Run the processing algorithm.

    Can be used without GUI widget.

    :param inputVolume: volume to be thresholded

    :param outputVolume: thresholding result

    :param imageThreshold: values above/below this threshold will be set to 0

    :param invert: if True then values above the threshold will be set to 0, otherwise values below are set to 0

    :param showResult: show output volume in slice viewers

    """

    if not inputVolume:

        raise ValueError("Input volume is invalid")

    import time

    startTime = time.time()

    logging.info("Processing started")

    volumeNode = slicer.util.getNode("5: CTA 0.5 CE")

    markupsIndex = 0

    point_Ras = \[0, 0, 0\]

    inputlowerpoint.GetNthControlPointPositionWorld(markupsIndex, point_Ras)

    

    transformRasToVolumeRas = vtk.vtkGeneralTransform()

    slicer.vtkMRMLTransformNode.GetTransformBetweenNodes(None, volumeNode.GetParentTransformNode(), transformRasToVolumeRas)

    point_VolumeRas = transformRasToVolumeRas.TransformPoint(point_Ras)

    \# Get voxel coordinates from physical coordinates

    volumeRasToIjk = vtk.vtkMatrix4x4()

    volumeNode.GetRASToIJKMatrix(volumeRasToIjk)

    point_Ijk = \[0, 0, 0, 1\]

    volumeRasToIjk.MultiplyPoint(np.append(point_VolumeRas,1.0), point_Ijk)

    point_Ijk = \[int(round(c)) for c in point_Ijk\[0:3\] \]

    print('lowerpoint : RAS =',point_Ras)

    print('lowerpoint : IJK =',point_Ijk)

    stopTime = time.time()

    logging.info(f"Processing completed in {stopTime-startTime:.2f} seconds")

```

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/6/f/6fd4f99f5d519128e5ecd605e4d8ee52379097ef.png)

---

<div class="post-metadata">

**Author:** ![zhutouzjq](https://avatars.discourse-cdn.com/v4/letter/z/8797f3/32.png) [@zhutouzjq](https://discourse.slicer.org/u/zhutouzjq)\
**Post date:** [December 4, 2025, 3:17am UTC](https://discourse.slicer.org/t/how-to-get-the-ijk-coordinate-of-a-fiducial-node-in-3d-slicer-development/45362/4 "2025-12-04T03:17:32Z")

</div>

thank you for your reply. with your discussion under the issue “[RAS to IJK conversion issues](https://discourse.slicer.org/t/ras-to-ijk-conversion-issues/41863)“, i have solve this problem. your are very professional in developping 3d slicer extension
