# Apply paint using code

**URL:** <https://discourse.slicer.org/t/apply-paint-using-code/36686>\
**Category:** Development\
**Tags:** segmentation, python\
**Created:** [June 10, 2024, 1:24pm UTC](https://discourse.slicer.org/t/apply-paint-using-code/36686 "2024-06-10T13:24:13Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Cagatay](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/cagatay/32/76895_2.png) [@Cagatay](https://discourse.slicer.org/u/Cagatay)\
**Post date:** [June 10, 2024, 1:24pm UTC](https://discourse.slicer.org/t/apply-paint-using-code/36686/1 "2024-06-10T13:24:13Z")

</div>

I want to put sphere brushes (i want to use paint) on scenes with given coordinates. But i couldnt find a way to use paint effect from segment editor in code. How can i use paint in code and paint the scene just in code().I’ve tried [this](https://gist.github.com/lassoan/2d5a5b73645f65a5eb6f8d5f97abf31b#file-segmentgrowcutsimple-py-L10-L34). but it uses grow from seeds and i dont want that. I just want to paint.

I also tried this but giving me error.

```auto
segmentEditorWidget.setActiveEffectByName("Paint")
effect = segmentEditorWidget.activeEffect()
effect.setParameter("BrushRelativeDiameter", "1") # Brush size relative to the volume size
effect.setParameter("BrushSphere", "1") # Use a spherical brush
effect.paintApply((255, 255, 674))

```

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [June 10, 2024, 1:25pm UTC](https://discourse.slicer.org/t/apply-paint-using-code/36686/2 "2024-06-10T13:25:16Z")

</div>

The code section you have found is perfect, that’s all you need to do. You can ignore the rest of the script.

---

<div class="post-metadata">

**Author:** ![Cagatay](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/cagatay/32/76895_2.png) [@Cagatay](https://discourse.slicer.org/u/Cagatay)\
**Post date:** [June 11, 2024, 6:54am UTC](https://discourse.slicer.org/t/apply-paint-using-code/36686/3 "2024-06-11T06:54:17Z")

</div>

![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/4/6/46897c62e90e595840491ca6209d68e0ee43ff05.png)  
I can see the spheres in the 3d view. But i cant see them on the slice views. I tried many times, but it doesnt appear.

```auto

masterVolumeNode = volumeNode = slicer.mrmlScene.GetFirstNodeByClass("vtkMRMLScalarVolumeNode")

segmentationNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")
segmentationNode.CreateDefaultDisplayNodes() # only needed for display
segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(masterVolumeNode)

# Create seed segment inside tumor
tumorSeed = vtk.vtkSphereSource()
tumorSeed.SetCenter(255, 255, 494)
tumorSeed.SetRadius(10)
tumorSeed.Update()
segmentationNode.AddSegmentFromClosedSurfaceRepresentation(tumorSeed.GetOutput(), "Tumor", [1.0,0.0,0.0])

# Create seed segment outside tumor
backgroundSeedPositions = [[255, 260, 494], [255, 265, 494], [255, 270, 494], [255, 275, 494], [255, 280, 494], [255, 285, 494]]
append = vtk.vtkAppendPolyData()
for backgroundSeedPosition in backgroundSeedPositions:
  backgroundSeed = vtk.vtkSphereSource()
  backgroundSeed.SetCenter(backgroundSeedPosition)
  backgroundSeed.SetRadius(10)
  backgroundSeed.Update()
  append.AddInputData(backgroundSeed.GetOutput())

append.Update()
backgroundSegmentId = segmentationNode.AddSegmentFromClosedSurfaceRepresentation(append.GetOutput(), "Background", [0.0,1.0,0.0])

```

This is the code i tried last, coordinates are close to the center in the green slice view but i cant see any paint in slice.  
Is there a way to solve this? Or how can i use paint effect? Thanks.

---

<div class="post-metadata">

**Author:** ![cpinter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/cpinter/32/7995_2.png) [@cpinter](https://discourse.slicer.org/u/cpinter)\
**Post date:** [June 11, 2024, 8:56am UTC](https://discourse.slicer.org/t/apply-paint-using-code/36686/4 "2024-06-11T08:56:00Z")

</div>

I see you decided to go a different way. This should work as well, but I never used `AddSegmentFromClosedSurfaceRepresentation` so not sure what it does exactly. When I do this, I tend to create a model node and use `slicer.vtkSlicerSegmentationsModuleLogic.ImportModelToSegmentationNode`.

As your code does not specify a closed surface representation, the default binary labelmap should be created from the added polydata segments, so not sure. It is always possible that the locations are not correct, so please verify by showing the slices in 3D (or volume render). I’d also check the representations part in the Segmentations module and see what is the master, and also check which representation is shown in 2D (in Display / Advanced I believe). Try to show the closed surface representation in 2D if it is the master for some reason.

---

<div class="post-metadata">

**Author:** ![Cagatay](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/cagatay/32/76895_2.png) [@Cagatay](https://discourse.slicer.org/u/Cagatay)\
**Post date:** [June 11, 2024, 12:59pm UTC](https://discourse.slicer.org/t/apply-paint-using-code/36686/5 "2024-06-11T12:59:19Z")

</div>

Thanks for the reply.

With these 3d spheres, this point markup F1 on the screen, when i put my cursor, looks like around 255,255,494 as you can see in the image(bottom-left). But it doesnt show on the axial slice any paint while showing on the 3d.

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

When i look at one slice and sphere paints in 3d, it looks like im giving the coordinates wrong. Where should i get the coordinates from?

![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/3/1/313bb561d450204cdea896280d879fd7bb731ece.png)

My main goal is to put 2d sphere brushes on some axial slices at the corners. So that it looks quarter sphere on the 3d. So my main goal is to put 2d spheres with paint on axial slice with code, but i cant find any example using paint effect. It should look like this.

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/2/f/2f317f0dccb087031b162623fdf01f04dce87fb6.jpeg)

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/a/0/a005cefc54ccf6e7d9093a8abee7e52fe9f89add.jpeg)

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [June 11, 2024, 4:28pm UTC](https://discourse.slicer.org/t/apply-paint-using-code/36686/6 "2024-06-11T16:28:15Z")

</div>

It seems that the centerpoint coordinates are not set correctly. If you create an example scene from one of the Slicer sample data sets and share that with us (saved as .mrb, uploaded to dropbox/onedrive/googledrive) and corresponding code snippet then we can tell where things went wrong.

What would you like to segment?

---

<div class="post-metadata">

**Author:** ![Cagatay](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/cagatay/32/76895_2.png) [@Cagatay](https://discourse.slicer.org/u/Cagatay)\
**Post date:** [June 12, 2024, 8:26am UTC](https://discourse.slicer.org/t/apply-paint-using-code/36686/7 "2024-06-12T08:26:16Z")

</div>

> **[Pictures.mrml](https://drive.google.com/file/d/1lPqGQr63QxN5sivbGb71bbwDWs1iqPx4/view?usp=sharing)**
>
> Google Drive file.

```auto
# Generate input data
################################################

masterVolumeNode = volumeNode = slicer.mrmlScene.GetFirstNodeByClass("vtkMRMLScalarVolumeNode")

# Load master volume

# Create segmentation
segmentationNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")
segmentationNode.CreateDefaultDisplayNodes() # only needed for display
segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(masterVolumeNode)

 

start_value = 170
increment = 40
num_iterations = 20

paint_positions = []

for i in range(num_iterations):
    third_element = start_value + i * increment
    paint_positions.extend([
        [0, 0, third_element],
        [0, 511, third_element],
        [511, 0, third_element],
        [511, 511, third_element]
    ])

append = vtk.vtkAppendPolyData()
for paint_position in paint_positions:
  print(paint_position)
  paintSphere = vtk.vtkSphereSource()
  paintSphere.SetCenter(paint_position)
  paintSphere.SetRadius(10)
  paintSphere.Update()
  append.AddInputData(paintSphere.GetOutput())
  
append.Update()

segmentationNode.AddSegmentFromClosedSurfaceRepresentation(append.GetOutput(), "Paint", [1.0,0.0,0.0])

# Run filter
################################################

# Create segment editor to get access to effects
segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
# To show segment editor widget (useful for debugging): segmentEditorWidget.show()
segmentEditorWidget.setMRMLScene(slicer.mrmlScene)

segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentEditorNode")
segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
segmentEditorWidget.setSegmentationNode(segmentationNode)
segmentEditorWidget.setSourceVolumeNode(masterVolumeNode)

 
# Clean up and show results
################################################

# Clean up
slicer.mrmlScene.RemoveNode(segmentEditorNode)

# Make segmentation results nicely visible in 3D
segmentationDisplayNode = segmentationNode.GetDisplayNode()

```

I am segmenting successfully using threshold in other code but i need to put spheres around the corners before exporting this segmentation model as you can see in the previous photos with 4 green quarter spheres, i did that manually but i have to do it in code. I couldnt manage to do that. Seems simple actually, just 4 paint brush in some slices corners in axial view 😑

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [June 12, 2024, 12:35pm UTC](https://discourse.slicer.org/t/apply-paint-using-code/36686/8 "2024-06-12T12:35:24Z")

</div>

The problem is that you specified the sphere center positions in voxel (IJK) coordinate system. In the code snippet above the positions are expected in patient (RAS) coordinate system. You can find examples in the script repository how to convert. Alternatively, in a special case like this when you want to paint borders you can get segmentation as a numpy array and modufy that using voxel indices (see examples in script repository).

---

<div class="post-metadata">

**Author:** ![Cagatay](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/cagatay/32/76895_2.png) [@Cagatay](https://discourse.slicer.org/u/Cagatay)\
**Post date:** [June 12, 2024, 5:31pm UTC](https://discourse.slicer.org/t/apply-paint-using-code/36686/9 "2024-06-12T17:31:43Z")

</div>

![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/c/7/c771639727fa823156cf81bd3a8cd17938961e63.png)  
Thank you very much. Now i converted coordinates and it puts the spheres on axial slices and i can see it. But what i really want is put sphere brushes with paint on corners so only quarter of sphere is shown in 3d view, like above two images with green quarter spheres.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [June 13, 2024, 1:42am UTC](https://discourse.slicer.org/t/apply-paint-using-code/36686/10 "2024-06-13T01:42:42Z")

</div>

You can set the segment geometry to not include the entire spheres. By the way, if you drew 4 tubes instead of hundreds of spheres then processing could be 100x faster. Or, if you just want to fill the corners then you can use numpy to modify the segment (e.g., `segArray[0:5, 0:5] = 1`).

---

<div class="post-metadata">

**Author:** ![Cagatay](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/cagatay/32/76895_2.png) [@Cagatay](https://discourse.slicer.org/u/Cagatay)\
**Post date:** [June 19, 2024, 8:04am UTC](https://discourse.slicer.org/t/apply-paint-using-code/36686/11 "2024-06-19T08:04:39Z")

</div>

I want to fill the corners with sphere paint brush in axial slice.

> segArray[0:5, 0:5] = 1

i didnt understand this. Are these 0 and 5 signify slice number? and what does assigning 1 do?

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [June 19, 2024, 11:39am UTC](https://discourse.slicer.org/t/apply-paint-using-code/36686/12 "2024-06-19T11:39:38Z")

</div>

`segArray` is a numpy array. The code sets the corner voxels to 1 in all axial slices (I think you can use any positive value). See a complete example [here](https://slicer.readthedocs.io/en/latest/developer_guide/script_repository.html#read-and-write-a-segment-as-a-numpy-array).
