Eshant
Eshant

Reputation: 75

Finding distance between skeleton and boundary using openCV python

I am trying to find maximum width of a curve using openCV in python. I used canny edge detector to get the boundaries of the curve. I have then managed to create a skeleton between them as shown by the red line in the attached image. I now need to find distance between this skeleton and the white line segments so that i can multiply the max distance by 2 to get the width. In short, i need the length of the blue line.

I tried using distance transform but i do not have a closed contour so i am getting incorrect width. I also tried dilation followed by erosion to get a closed contour but that changes the width of my curve. Stuck on this for a long time. Any help would be highly appreciated.

Upvotes: 1

Views: 2476

Answers (1)

jmetz
jmetz

Reputation: 12783

The maximum width is the maximal distance of any point on the boundary to the mid-line (multiplied by two perhaps).

To determine this value, you can use the distance_transform as follows:

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

# Generate test image
size = (100, 100)

mid_line = np.zeros(size, dtype='uint8')
mid_line[(range(10, 40), range(10, 40))] = 1
mid_line[(range(40, 80), np.linspace(40, 70, 40).astype(int))] = 1

outline = np.zeros(size, dtype='uint8')
outline[(np.linspace(5, 33, 30).astype(int),
         np.linspace(16, 47, 30).astype(int))] = 1

outline[(np.linspace(14, 47, 30).astype(int),
         np.linspace(5, 35, 30).astype(int))] = 1

outline[(np.linspace(36, 72, 40).astype(int),
         np.linspace(50, 77, 40).astype(int))] = 1

outline[(np.linspace(47, 88, 40).astype(int),
         np.linspace(35, 65, 40).astype(int))] = 1

dist = cv2.distanceTransform(255 - (255*mid_line), cv2.DIST_L2, 3)

# Visualize
plt.figure("Mid line plus edges over the distance transform")
plt.imshow(dist, cmap='gray')
overlay = mid_line + 2 * outline
plt.imshow(np.ma.masked_where(overlay == 0, overlay), cmap='jet', alpha=0.6)

# Get the maximum width
max_width = np.max(dist[outline > 0])
print("Maximum width:", max_width)


plt.show()

which generates the image:

enter image description here

And outputs:

Maximum width: 10.954346

to the terminal.

Upvotes: 4

Related Questions