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

2024-09-30 08:37:14 发布

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

我正在用OpenCv for python进行对象检测:我使用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)

enter image description here

问题是,有时在同一帧中检测到两个图像,而平均法(给出两个坐标的中间)不起作用

enter image description here

你有什么(非天真的)想法如何为2,3,4做到这一点。。。检测到的图像

谢谢:)


Tags: 对象方法图像foropencv平均值matchtemplate平均法
1条回答
网友
1楼 · 发布于 2024-09-30 08:37:14

我的代码既不完美也不最优;但这可能是一个好的开始:)

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()

这段代码不能解决集群数量的问题,如果您知道集群的数量,我认为它目前很有用

enter image description here


更新:

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


更新:

我更多地考虑了解释和讨论。我认为如果你有一个来自points的面具,如果你尝试这样的东西可能不是最坏的主意:

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)))

enter image description here

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

相关问题 更多 >

    热门问题