Daiver
Daiver

Reputation: 1508

How to draw a circle on image given float (subpixel) coordinates of it center

I want to visualize results of keypoint tracking algorithm in python. I have a sequence of (Image, Keypoint) pairs (video basically). Tracking algorithm is strong enough to give me subpixel accuracy. But i have no idea, how to visualize it properly.

I tried to round my coordinates and draw a circle by cv2.circle(image, (int(round(x)), int(round(y)))), but it leads to visual jittering of my keypoints due to small image resolution.

I checked OpenCV, Pillow, skimage, Pygame (pygame.draw.circle). All of them cannot properly draw circle with float coordinates.

Upvotes: 0

Views: 1557

Answers (1)

Cris Luengo
Cris Luengo

Reputation: 60790

DIPlib has the function DrawBandlimitedBall(), which draws a disk or a circle with smooth transitions and with floating-point origin coordinates (disclosure: I'm one of the authors). You might need to draw the circle in an empty image, then blend it in to get the effect you are looking for. Code would look something like this:

import diplib as dip

img = dip.ImageRead('/Users/cris/dip/images/flamingo.tif')
p = [366.4, 219.1]

# Create an empty image and draw a circle in it
circle = dip.Image(img.Sizes(), 1, 'SFLOAT')
circle.Fill(0)
dip.DrawBandlimitedBall(circle, diameter=22.3, origin=p, value=1, mode='empty')
circle /= dip.Maximum(circle)

# Blend: img * (1-circle) + circle * color
img *= 1 - circle
img += circle * dip.Create0D([0,255,0]) # we make the circle green here

img.Show()
dip.ImageWrite(img, 'so.jpg')

flamingo image with a green circle added

(Note that the circle actually looks better without the JPEG compression artifacts.)

You could draw the circle directly in the image, but this function adds the circle values to the image, it doesn't attempt to blend, and so you'd get a much worse look for this particular application.

Upvotes: 2

Related Questions