如何找到一组轮廓的质心?

tyr*_*675 0 python opencv

我有一组小圆圈的图像。每个圆都是一个单独的轮廓。我需要在不使用图像过滤或形态学的情况下找到整个组的质心。

洞

我的想法是将所有圆形轮廓组合成一个巨大的轮廓,然后使用 cv2 矩来找到质心,但这是不准确的。这是我正在使用的代码(我可以成功找到每个孔作为轮廓,因此我将该代码保留在下面的代码片段之外:

找到所有孔轮廓后的图像: 在此输入图像描述

# holes is a list of all hole contours
combined_conts = np.concatenate(holes)

cont_moment = cv2.moments(combined_conts)
cX = int(cont_moment["m10"] / cont_moment["m00"])
cY = int(cont_moment["m01"] / cont_moment["m00"])
Run Code Online (Sandbox Code Playgroud)

我希望 cX 和 cY 坐标靠近该组孔的中心,但它们甚至不接近(它们靠近该组的右上角)。我怀疑 cv2.moments 不喜欢轮廓的组合方式?有没有更好的方法将轮廓合并为一个?

当孔组合成一个轮廓时,图像如下所示: 在此输入图像描述

fmw*_*w42 7

这是在 Python/OpenCV 中获取质心的简单方法。只需从阈值(二值)图像中获取质心即可。零值像素(黑色)对这些时刻没有贡献。

输入:

在此输入图像描述

import cv2
import numpy as np

# read the input
img = cv2.imread('holes.png')

# convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# threshold
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# get centroid
M = cv2.moments(thresh)
cx = int(M["m10"] / M["m00"])
cy = int(M["m01"] / M["m00"])       
print('cx:', cx, 'cy:', cy)

# draw centroid
result = img.copy()
x = int(cx)
y = int(cy)
r = 1
cv2.circle(result, (x, y), r, (0, 0, 255), 2)

# save results
cv2.imwrite('holes_centroid.png', result)

# show results
cv2.imshow('thresh', thresh)
cv2.imshow('result', result)
cv2.waitKey(0)
Run Code Online (Sandbox Code Playgroud)

质心:

cx: 101 cy: 245
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述