I'm interested in calculating the average minimum distance between elements of two sets of contours.
Here's my code so far:
import cv2
import numpy as np
def contours(layer):
gray = cv2.cvtColor(layer, cv2.COLOR_BGR2GRAY)
ret,binary = cv2.threshold(gray, 1,255,cv2.THRESH_BINARY)
image, contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
drawn = cv2.drawContours(image,contours,-1,(150,150,150),3)
return contours, drawn
def minDistance(contour, contourOther):
distanceMin = 99999999
for xA, yA in contour[0]:
for xB, yB in contourOther[0]:
distance = ((xB-xA)**2+(yB-yA)**2)**(1/2) # distance formula
if (distance < distanceMin):
distanceMin = distance
return distanceMin
def cntDistanceCompare(contoursA, contoursB):
cumMinDistList = []
for contourA in contoursA:
indMinDistList = []
for contourB in contoursB:
minDist = minDistance(contourA,contourB)
indMinDistList.append(minDist)
cumMinDistList.append(indMinDistList)
l = cumMinDistList
return sum(l)/len(l) #returns mean distance
def maskBuilder(bgr,hl,hh,sl,sh,vl,vh):
hsv = cv2.cvtColor(bgr, cv2.COLOR_BGR2HSV)
lower_bound = np.array([hl,sl,vl],dtype=np.uint8)
upper_bound = np.array([hh,sh,vh],dtype=np.uint8)
return cv2.inRange(hsv, lower_bound,upper_bound)
img = cv2.imread("sample.jpg")
maskA=maskBuilder(img, 150,185, 40,220, 65,240)
maskB=maskBuilder(img, 3,20, 50,180, 20,250)
layerA = cv2.bitwise_and(img, img, mask = maskA)
layerB = cv2.bitwise_and(img, img, mask = maskB)
contoursA = contours(layerA)[0]
contoursB = contours(layerA)[1]
print cntDistanceCompare(contoursA, contoursB)
As you can see from these images, the masking and thesholding works (shown for the first set of contours):
The cntDistanceCompare() function loops through each contour of set A and B, outputting average minimum distance between contours. Within this function, minDistance() calculates from the (x,y) points on each set of contours A and B a minimum pythagorean distance (using the distance formula).
The following error is thrown: Traceback (most recent call last): File "mindistance.py", line 46, in cntDistanceCompare(contoursA, contoursB) File "mindistance.py", line 26, in cntDistanceCompare minDist = minDistance(contourA,contourB) File "mindistance.py:, line 15, in minDistance for xB, yB in contourOther[0]: TypeError: 'numpy.uint8' object is not iterable
I suspect this problem arises from my lack of knowledge of how to reference the x,y coordinates of each contour vertex within the data structre given by cv2.findContours().