Question

Calculate distances in a shape with Python

I want to calculate the min vertical distance and max horizontal distance of this image.

enter image description here

Like the lines.

I was trying:

_, binary_image = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY)

horizontal_distances = np.sum(binary_image==255, axis=1)
max_horizontal_distance = np.max(horizontal_distances)

vertical_distances = np.sum(binary_image==255, axis=0)
min_vertical_distance = np.min(vertical_distances)

But min_vertical_distance returns 11, which is not accurate.

 2  119  2
1 Jan 1970

Solution

 0

To find the minimum vertical distance, you should ignore zero distances and find the smallest non-zero value using the following code:

min_vertical_distance = np.min(vertical_distances[np.nonzero(vertical_distances)])

This method should return a min_vertical_distance of 2.

2024-07-21
UsangR01

Solution

 0

IIUC, you want the length of the major and minor axis. If so, you can clip the image/mask to its bounding box then look for the confluence point (something like a Cassini Oval) :

box = np.c_[np.where(binary_image > 0)]
xmin, ymin = box.min(axis=0)
xmax, ymax = box.max(axis=0)

clip = binary_image[ymin:ymax, xmin:xmax]

def confluence(arr):
    spoints = (arr[:-1] < 0) & (arr[1:] >= 0)
    return np.where(spoints)[0][-1] + 1

major = (binary_image // 255).sum(axis=1).max()  # 301
minor = (clip[:, confluence(np.diff(clip.sum(axis=0)))] // 255).sum()  # 173

Note that if you're sure to have a summetric oval, the minor can be simplified to (clip[:, clip.shape[0] // 2] // 255).sum().

Used input :

enter image description here

from shapely import Point, unary_union
from skimage.draw import polygon2mask

poly = unary_union([
    Point(200, 200).buffer(100),
    Point(300, 200).buffer(100)
])

coords = np.array(poly.exterior.coords)
binary_image = polygon2mask((500, 400), coords).T.astype(int) * 255
2024-07-21
Timeless