# Quantify longest axis and width of irregular shapes within a single image

## Issue

Original question

I have about 80-100 images such as (A). Each image is composed of shapes that were filled with black color after marking the outline in ImageJ. I need to extract each individual shape as in (B). I then need to find the widths of the longest axis as in (C).

And I then need to calculate all the possible widths at regular points within the black shape and return a .csv file containing these values.

I have been doing this manually and there must be a quicker way to do it. Any idea how I can go about doing this?

Partial solution as per Epsi’s answer

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

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Find contours, find rotated rectangle, obtain four verticies, and draw
contours, hierarchy = cv2.findContours(thresh_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

lengths = []
for i in contours:

x_y,width_height,angle_of_rotation = cv2.minAreaRect(i)
Height = print(width_height[1])
rect = cv2.minAreaRect(i)
box = np.int0(cv2.boxPoints(rect))
image_contours = np.zeros(image.shape)
# draw the contours on the empty image
cv2.drawContours(image, [box], 0, (36,255,12), 3) # OR
# cv2.polylines(image, [box], True, (36,255,12), 3)
plt.imshow(image)

cv2.imwrite(output,image)
``````

Output:

``````4031.0
20.877727508544922
51.598445892333984
23.852108001708984
21.0
21.21320343017578
19.677398681640625
43.0
``````

I am able to get the length of each shape. I next need to figure out how to get width of the shape at regular points along the length of the shape?

## Solution

As I’m not that good with python, I wont post code, but will post links to explanations and documentary.

How I would do it is as follows:

1. Invert the image, so that all the white becomes black and black becomes white. https://www.delftstack.com/howto/python/opencv-invert-image/#invert-images-using-numpy.invert-method-in-python

2. Use findContours to find all the (now) white contours. https://pythonexamples.org/python-opencv-cv2-find-contours-in-image/

3. use minAreaRect to create bounding boxes around the contours that is positioned in a way that the area of the box is as small as possible. https://theailearner.com/tag/cv2-minarearect/

4. from the created bounding boxes, take the longest side, this will represent the length of your contour.

5. You can also get the angle of rotation from the bounding boxes