在图片中查找聚类 opencv/python

finding clusters in a picture opencv/python

寻找图像中“簇”/“圆”/“椭圆”等的中心点。

示例图片:

目测清楚,有3个左右的簇。我正在寻找簇的中心点,以及定义 - 矩形或圆形(带半径)或椭圆形,但是要描述它。

理想情况下,扩展为以下情况:

  1. 如果需要,为简单起见,未知的簇数(假设最小 1,最大 10)。

这张图片是一张较大图片的一部分,该图片使用精巧的边缘检测、阈值处理和轮廓来找到我感兴趣的区域。不幸的是,我需要它...更精致(或更好的参数,但我找不到任何有用的东西)

我尝试过的事情:

我尝试过使用kmeans分割,但它们主要用于颜色分割。对于颜色给我们的所有信息,这张图片可能是 black/white。 opencv 中的 HughCircles 并不是我真正想要的圆圈,因为它们给了我太多与“边缘”匹配的圆圈 通过 opencv 进行的模板匹配也没有用,因为它太受限制并且不能完全匹配。

欢迎任何 suggestions/avenues 检查!
我也尝试了一些基本的散点图 k 均值聚类(好像这是数据)但到目前为止还没有取得好的结果。

选择的语言:python,但适应性强。

我对此进行了尝试,它可能会给您一些关于如何继续的想法 - 即使只是通过查看它无法工作的地方。我想 post 在问题获得第三次接近投票之前解决它。

#!/usr/bin/env python3

import cv2
import numpy as np

# Load image and make greyscale version too
im = cv2.imread('dl9Vx.png')
grey = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)

# Threshold (in case we do morphology) and invert
_, thresh = cv2.threshold(grey, 254, 255, cv2.THRESH_BINARY_INV)
cv2.imwrite('DEBUG-thresh.png', thresh)

# Prepare to do some K-means
# https://docs.opencv.org/4.x/d1/d5c/tutorial_py_kmeans_opencv.html
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
# Find x,y coordinates of all non-white pixels in original image
Y, X = np.where(thresh==255)
Z = np.column_stack((X,Y)).astype(np.float32)

nClusters = 3
ret,label,center=cv2.kmeans(Z,nClusters,None,criteria,10,cv2.KMEANS_RANDOM_CENTERS)

# Mark and display cluster centres 
for x,y in center:
    print(f'Cluster centre: [{int(x)},{int(y)}]')
    cv2.drawMarker(im, (int(x), int(y)), [0,0,255])

cv2.imwrite('result.png', im)

输出

Cluster centre: [103,65]
Cluster centre: [50,93]
Cluster centre: [60,29]


备注:

注 1:我要求它搜索 3 个簇,因为那是你建议的数字。有一些自动确定簇数的方法 - 例如搜索 “弯头法”

注2:如果你想对间隙进行形态学上的闭合,使簇更坚固,你可以在cv2.threshold()之后添加这段代码:

kernel = np.ones((3,3),np.uint8)
thresh = cv2.dilate(thresh, kernel, iterations=1)

它会使阈值图像看起来像这样:

注3:

您可以删除阈值调用并将 np.where() 行更改为:

Y, X = np.where(im!=255)