如何从坐标列表中确定区域?

How to determine regions out of a list of coordinates?

我正在为 python 的 OpenCv 对象检测而苦苦挣扎:我使用 matchTemplate 方法检测图像,但结果以同一对象的多个坐标结尾。

[(798, 540), (799, 540), (800, 540), (798, 541), (799, 541), (800, 541), (798, 542), (799, 542), (800, 542), (798, 543), (799, 543), (800, 543), (798, 544), (799, 544), (800, 544)]

我只想为每张检测到的图像设置一个坐标,所以我应用了所有坐标的平均值,结果很好(图像上的红点):(799, 542)

问题是有时在同一帧中检测到两张图像,并且它不适用于平均方法(给出两个坐标的中间)。

对于如何对 2、3、4... 检测到的图像执行此操作,您有任何(非天真的)想法吗?

谢谢:)

我的代码既不完美也不优化;但开始可能会很好 :)

import matplotlib.pyplot as plt
import numpy as np
import random
import math

# 'o': without cluster
# '*': first cluster
# '^': second cluster
pts = [
    [6.0, 4.0, 'o'], [1.0, 2.0, 'o'], [2.0, 1.0, 'o'], [2.0, 2.0, 'o'],
    [6.0, 6.0, 'o'], [6.0, 5.0, 'o'], [5.0, 6.0, 'o'], [5.0, 5.0, 'o']
]

def distance(pt1, pt2):
    return math.hypot(pt1[0] - pt2[0], pt1[1] - pt2[1])

def getRandomPoint():
    rnd = random.randint(0, len(pts)-1)
    return [pts[rnd][0], pts[rnd][1]]

def plotClusterCenter(c='o'):
    s = []
    for p in pts:
        if p[2] == c:
            s.append(p)
    print(s)
    cx, cy = np.mean([d[0] for d in s]), np.mean([d[1] for d in s])
    plt.plot(cx, cy, c, c=(1, .5, 0))


x, y, c = [d[0] for d in pts], [d[1] for d in pts], [d[2] for d in pts]
A, B = getRandomPoint(), getRandomPoint()


for _ in range(0, len(pts)//2):
    for i in range(0, len(x)):
        if c[i] == "*":
            A = [(A[0] + x[i]) / 2, (A[1] + y[i]) / 2]
        else:
            B = [(B[0] + x[i]) / 2, (B[1] + y[i]) / 2]
        pt = (x[i], y[i])
        c[i] = "*" if distance(A, pt) < distance(B, pt) else "^"
        pts[i][2]=c[i]

for i in range(0, len(x)):
    plt.plot(x[i], y[i], c[i], c=(0, 0, 0))

plotClusterCenter('*')
plotClusterCenter('^')
plt.show()

这段代码不能解决簇数的问题,如果你知道簇数,我认为目前有用。


更新:

阅读评论后(尤其是@Christoph Rackwitz 的完整描述);我得出的结论是,我提出的方法可能不正确。


更新:

我想的更多的是解释和讨论。我想如果你有一个来自点的面具,如果你尝试这样的事情可能不是最糟糕的主意:

import sys
import cv2
import numpy as np

org = cv2.imread(sys.path[0]+'/mask.png')
im = org.copy()
H, W = org.shape[:2]

gry = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
gry = cv2.erode(gry, np.ones((31, 31)))

cnts, _ = cv2.findContours(gry, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
for cnt in cnts:
    x, y, w, h = cv2.boundingRect(cnt)
    if w < W:
        cv2.rectangle(im, (x, y), (x+w, y+h), (50, 250, 10), 2)
        cv2.circle(im,  (x+w//2, y+h//2),3, (240, 20, 100), 3)

cv2.imwrite(sys.path[0]+'/output.png', np.hstack((org, im)))

在这种情况下,您可以找到聚类、它们的范围以及每个聚类的大致中心。在下一步中,您可以更详细地检查每个集群的范围。