Skip to content

Dear Internet Explorer user: Your browser is no longer supported

Please switch to a modern browser such as Microsoft Edge, Mozilla Firefox or Google Chrome to view this website's content.

Fit an inscribing circle to a shape in OpenCV

The largest possible circle that can be drawn interior to a plane figure is called an inscribing circle. This can easily be fitted to a binary shape in OpenCV.

Let’s use a 939×1100 px RGB image of Australia, supplied by the Bureau of Meteorology, for this example.

A RGB image of Australia, in PNG format.

To begin, libraries need to be loaded and the image needs to be read into OpenCV. I am using OpenCV 4.5.3.56 with Python (3.9.7) on Windows 11. The other required libraries are Matplotlib (I am using 3.4.3) and NumPy (I am using 1.21.2):

import cv2
import matplotlib.pyplot as plt
import numpy as np

img = cv2.imread("/path/to/australia.png")

Once the image is read-in, it needs to be converted from RGB to 8-bit greyscale (uint8):

grey = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
A uint8 greyscale image of Australia.

Next, the image needs to be thresholded into a binary such that the foreground (Australia) is white:

ret, thresh = cv2.threshold(grey, 254, 255, cv2.THRESH_BINARY)
thresh_inv = cv2.bitwise_not(thresh)
A binary image of Australia, with the landmass as foreground (white).

Next, perform a distance transform on the binary image:

distance = cv2.distanceTransform(thresh_inv, cv2.DIST_L2, cv2.DIST_MASK_PRECISE)
A distance transform of the binary image of Australia.

For the inscribing circle, the greatest value in the distance transform is the radius and its position is the centre. These values can be extracted from the distance transform using the cv2.minMaxLoc() function and then applied to the cv2.circle function to draw the circle on the original image.

_, max_val, _, centre = cv2.minMaxLoc(distance)
circle = cv2.circle(img, centre, int(max_val), (255, 0, 0), 2)
The picture of Australia with its inscribing circle drawn as an overlay.

These values can also be reported:

print("Max value:", max_val, "Position:", centre)

Max value: 221.73182678222656 Position: (515, 347)

   

Comments

No comments have yet been submitted. Be the first!

Have Your Say

The following HTML is permitted:
<a href="" title=""> <b> <blockquote cite=""> <code> <em> <i> <q cite=""> <strike> <strong>

Comments will be published subject to the Editorial Policy.