OpenCV:任意大轮廓集之间的最小距离(Python)

2024-05-20 21:28:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我对计算两组等高线元素之间的平均最小距离感兴趣。在

下面是一个示例图像: sample image

以下是我目前为止的代码:

    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)

从这些图像中可以看到,遮罩和保持工作正常(如第一组轮廓所示): tresholded Acontours A

函数的作用是:循环遍历集合A和B的每个轮廓,输出轮廓之间的平均最小距离。在该函数中,minDistance()从轮廓A和B每组上的(x,y)点计算最小毕达哥拉斯距离(使用距离公式)。在

将引发以下错误: 回溯(最近一次呼叫): “文件”思维距离.py“,第46行,英寸 CNT距离比较(contoursA,contoursB) “文件”思维距离.py,第26行,在cntDistanceCompare中 Mindsist=心灵距离(contourA,contourB) “文件”思维距离.py:,15号线,在远处 对于contourOther[0]中的xB、yB: 类型错误:'纽比.uint8'对象不可编辑

我怀疑这个问题是因为我不知道如何引用cv2.findConteurs()给出的数据结构中每个轮廓顶点的x,y坐标。在


Tags: in距离imgforreturndefnpcv2
1条回答
网友
1楼 · 发布于 2024-05-20 21:28:09

我使用的是一个旧版本的openCV,其中findContours只返回两个值,但希望这段代码的重要部分是有意义的。我没有测试你的功能,但我展示了如何得到轮廓中心。你必须用“瞬间”来做一些事情

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)

编辑:我现在在玩你的函数,我担心我误读了这个问题。告诉我,我会删除我的答案。在

相关问题 更多 >