'Quantify longest axis and width of irregular shapes within a single image
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
image = cv2.imread("Desktop/Analysis/NormalCol0.tif")
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 1:[1]
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:
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
Use findContours to find all the (now) white contours. https://pythonexamples.org/python-opencv-cv2-find-contours-in-image/
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/
from the created bounding boxes, take the longest side, this will represent the length of your contour.
You can also get the angle of rotation from the bounding boxes
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |