在图片中查找聚类 opencv/python
finding clusters in a picture opencv/python
寻找图像中“簇”/“圆”/“椭圆”等的中心点。
示例图片:
目测清楚,有3个左右的簇。我正在寻找簇的中心点,以及定义 - 矩形或圆形(带半径)或椭圆形,但是要描述它。
理想情况下,扩展为以下情况:
- 如果需要,为简单起见,未知的簇数(假设最小 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)
寻找图像中“簇”/“圆”/“椭圆”等的中心点。
示例图片:
目测清楚,有3个左右的簇。我正在寻找簇的中心点,以及定义 - 矩形或圆形(带半径)或椭圆形,但是要描述它。
理想情况下,扩展为以下情况:
- 如果需要,为简单起见,未知的簇数(假设最小 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)