我有兴趣计算两组轮廓元素之间的平均最小距离。
到目前为止,这是我的代码:
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)
cntDistanceCompare()函数循环遍历集合A和B的每个轮廓,输出轮廓之间的平均最小距离。在此函数中,minDistance()从每组轮廓A和B上的(x,y)点计算最小毕达哥拉斯距离(使用距离公式)。
抛出以下错误: Traceback(最近一次调用最后一次): 文件&#34; mindistance.py&#34;,第46行,in cntDistanceCompare(contoursA,contoursB) 在cntDistanceCompare中输入&#34; mindistance.py&#34;,第26行 minDist = minDistance(contourA,contourB) 文件&#34; mindistance.py:,第15行,在minDistance中 for xO,yB in contourOther [0]: TypeError:&#39; numpy.uint8&#39;对象不可迭代
我怀疑这个问题是由于我缺乏如何在cv2.findContours()给出的数据结构中引用每个轮廓顶点的x,y坐标的知识。
答案 0 :(得分:1)
我使用的是旧版本的openCV,其中findContours
只返回两个值,但希望此代码的重要部分有意义。我没有测试你的功能,但我确实展示了如何获得轮廓中心。你必须在&#34;时刻做一些事情。&#34;
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)
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)
def getContourCenters(contourData):
contourCoordinates = []
for contour in contourData:
moments = cv2.moments(contour)
contourX = int(moments['m10'] / float(moments['m00']))
contourY = int(moments['m01'] / float(moments['m00']))
contourCoordinates += [[contourX, contourY]]
return contourCoordinates
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)
contoursB = contours(layerB)
print getContourCenters(contoursA)
print getContourCenters(contoursB)
#print cntDistanceCompare(contoursA, contoursB)
编辑:我现在正在玩你的功能,我担心我误解了这个问题。让我知道,我将删除我的答案。