I am currently working on a project using opencv and python to measure objects that are usually curved for example the arrow shown below as accurately as possible.
I thought that one strategy might be to use the scipy Voronoi function to obtain the points along the center spine of the arrow but am having trouble right now. Here is my code:
img = cv2.imread('example_rubystreak_2.PNG')
img.shape
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,190,255,cv2.THRESH_BINARY)
countimage, contours, hierarchy = cv2.findContours(thresh,1,2)
blank = np.zeros((img.shape[0],img.shape[1],1),np.uint8)
#get max length contour
max_contour = 0
contour_idx = None
for ii in range(len(contours)):
if len(contours[ii]) > max_contour:
contour_idx = ii
max_contour = len(contours[ii])
cv2.drawContours(blank,contours,contour_idx,255,cv2.FILLED,8,hierarchy)
apdp = cv2.approxPolyDP(contours[contour_idx],1,True)
ap = [(a[0][0],a[0][1]) for a in apdp]
vor_ap = Voronoi(ap)
spined = []
for ridge in vor_ap.ridge_vertices:
if cv2.pointPolygonTest(cnt,tuple(vor_ap.vertices[ridge[0]]),True) <= 0.0 or cv2.pointPolygonTest(cnt,tuple(vor_ap.vertices[ridge[1]]),True) <= 0.0:
continue
else:
if tuple(vor_ap.vertices[ridge[0]]) not in spined:
spined.append([tuple(vor_ap.vertices[ridge[0]].tolist()),cv2.pointPolygonTest(cnt,tuple(vor_ap.vertices[ridge[0]]),True)])
if tuple(vor_ap.vertices[ridge[1]]) not in spined:
spined.append([tuple(vor_ap.vertices[ridge[1]].tolist()),cv2.pointPolygonTest(cnt,tuple(vor_ap.vertices[ridge[1]]),True)])
plt.figure(figsize=(12,12))
plt.scatter([s[0][0] for s in spined],[s[0][1] for s in spined])
plt.plot([a[0] for a in ap],[a[1] for a in ap])
Which produces this picture:
Anyone have ideas as to how I can then measure the length of the arrow using these center points? I've tried using np.polyfit and looked at the page here but can't figure out a way to consistently get the curve traced out by the most central points as the arrows are sometimes curved like an S or have different shaped points. Any help would be really appreciated. Thanks.