My idea would be to get the contour of the shape, try to detect "corners", e.g. using Harris corner detection, find matching points from the contour, and piecewise calculate the length of the edges using cv2.arcLength.
The input for the below extract_and_measure_edges method needs some binarized contour image like that one derived from your actual input image:

So, the pre-processing must be adapted to the input images, and is out of scope of my answer! In the below code, the pre-processing is for the given input image, not for the two other examples.
import cv2
import matplotlib.pyplot as plt
import numpy as np
def extract_and_measure_edges(img_bin):
# Detect possible corners, and extract candidates
dst = cv2.cornerHarris(img_bin, 2, 3, 0.04)
cand = []
for i, c in enumerate(np.argwhere(dst > 0.1 * np.max(dst)).tolist()):
c = np.flip(np.array(c))
if len(cand) == 0:
cand.append(c)
else:
add = True
for j, d in enumerate(cand):
d = np.array(d)
if np.linalg.norm(c - d) < 5:
add = False
break
if add:
cand.append(c)
# Get indices of actual, nearest matching contour points
corners = sorted([np.argmin(np.linalg.norm(c - cnt.squeeze(), axis=1))
for c in cand])
# Extract edges from contour, and measure their lengths
output = cv2.cvtColor(np.zeros_like(img_bin), cv2.COLOR_GRAY2BGR)
for i_c, c in enumerate(corners):
if i_c == len(corners) - 1:
edge = np.vstack([cnt[c:, ...], cnt[0:corners[0], ...]])
else:
edge = cnt[c:corners[i_c + 1], ...]
loc = tuple(np.mean(edge.squeeze(), axis=0, dtype=int).tolist())
color = tuple(np.random.randint(0, 255, 3).tolist())
length = cv2.arcLength(edge, False)
cv2.polylines(output, [edge], False, color, 2)
cv2.putText(output, '{:.2f}'.format(length), loc, cv2.FONT_HERSHEY_COMPLEX, 0.5, color, 1)
return output
# Read and pre-process image, extract contour of shape
# TODO: MODIFY TO FIT YOUR INPUT IMAGES
img = cv2.imread('2B2m4.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thr = cv2.threshold(gray, 16, 255, cv2.THRESH_BINARY_INV)[1]
cnts = cv2.findContours(thr, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
cnt = max(cnts, key=cv2.contourArea)
thr = cv2.drawContours(np.zeros_like(thr), [cnt], -1, 255, 1)
# Extract and measure edges, and visualize output
out = extract_and_measure_edges(thr)
plt.figure(figsize=(18, 6))
plt.subplot(1, 3, 1), plt.imshow(img), plt.title('Original input image')
plt.subplot(1, 3, 2), plt.imshow(thr, cmap='gray'), plt.title('Contour needed')
plt.subplot(1, 3, 3), plt.imshow(out), plt.title('Results')
plt.tight_layout(), plt.show()
That's the output:

Example #2:

Output:

Example #3:

Output:

(I haven't paid attention to the correct color ordering...)
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.19041-SP0
Python: 3.9.1
PyCharm: 2021.1.1
Matplotlib: 3.4.2
NumPy: 1.19.5
OpenCV: 4.5.2
----------------------------------------