0

The skimage.draw module has functions to draw circles, ellipses, lines, etc. However the line width seems to be fixed at 1 pixel. There doesn't appear to be a parameter to set the line width.

Stefan van der Walt suggested that there is hidden functionality in the skimage.measure submodule to draw thicker lines, but I had a look at the documentation and only saw the profile_line function which does have a linewidth parameter. I don't know if this what he meant, or how I can use that to draw an ellipse with width=3.

So how can I draw an ellipse with thickness of 3 pixels into a numpy image array (type float)? Preferably using skimage.

BrendanSimon
  • 665
  • 1
  • 9
  • 23

2 Answers2

1

I would use draw to draw a 1-pixel thick line, then use skimage.morphology.dilation to "thicken" that line:

import numpy as np
import matplotlib.pyplot as plt
from skimage import draw, morphology

image = np.zeros((128, 128))
rr, cc = draw.ellipse_perimeter(64, 64, 20, 10)
image[rr, cc] = 1
dilated = morphology.dilation(image, morphology.disk(radius=1))
fig, (ax0, ax1) = plt.subplots(1, 2)
ax0.imshow(image)
ax1.imshow(dilated)

original(left) vs dilated(right)

Juan
  • 5,433
  • 21
  • 23
  • (Stéfan's remark applies to the *source code* of `profile_line`, and anyway you could only use that to draw straight lines.) – Juan Nov 01 '19 at 01:44
  • That's awesome. I haven't looked at the morphology submodule. I will check it out see what other goodies it has. – BrendanSimon Nov 02 '19 at 05:17
  • The other thing I want to do is annotate the ellipse on to a bitmap. That's easy to do with the 1 pixel (rr,cc) output from `draw.ellipse_perimeter()`, but how can I do that with `morphology.dilation()`? Maybe for a 3 pixiel wide ellipse it might be just as easy to draw 3 ellipses onto the bitmap, each with radius = r - 1, r, r + 1 ?? – BrendanSimon Nov 02 '19 at 05:20
  • 1
    Draw as above onto a *boolean* array of zeros, then do `target_image[ellipse_boolean] = target_annotation_color`. – Juan Nov 04 '19 at 03:37
0

I am trying to do the same thing. Fortunately I just need to draw a bounding box, so I do it iteratively this way. Not sure whether this approach is applicable to other shape or not.

for i in range(0,thickness):
    rect = skimage.draw.rectangle_perimeter(start=(b[1]-i,b[0]-i)
                  ,end(b[3]+i,b[2]+i),shape=(1024,1024))
    skimage.draw.set_color(img_with_box,rect,(1.0,-1,-1))
jerryIsHere
  • 361
  • 2
  • 4