OpenCV 获取多个对象的中心
OpenCV get centers of multiple objects
我正在尝试构建一个简单的图像分析工具,该工具将找到适合颜色范围的项目,然后找到所述对象的中心。
例如,在蒙版之后,我正在分析这样的图像:
到目前为止我在代码方面所做的事情相当简单:
import cv2
import numpy
bound = 30
inc = numpy.array([225,225,225])
lower = inc - bound
upper = inc + bound
img = cv2.imread("input.tiff")
cv2.imshow("Original", img)
mask = cv2.inRange(img, lower, upper)
cv2.imshow("Range", mask)
contours = cv2.findContours(mask, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_TC89_L1)
print contours
然而,这给了我无数的轮廓。看the corresponding manpage的时候有些不知所措。能否利用矩合理分析轮廓?轮廓甚至是正确的工具吗?
我发现 this question,它模糊地涵盖了寻找一个对象的中心,但是当有多个项目时我该如何修改这种方法?
如何找到图像中对象的中心?例如,在上面的示例图像中,我正在寻找三个点(矩形和两个圆的中心)。
您可以在轮廓上使用 opencv minEnclosingCircle()
函数来获取每个对象的中心。
查看这个用 C++ 编写的示例,但您可以调整逻辑 Example
尝试print len(contours)
。这将为您提供预期的答案。您看到的输出是轮廓的完整表示,可能有数千个点。
试试这个代码:
import cv2
import numpy
img = cv2.imread('inp.png', 0)
_, contours, _ = cv2.findContours(img.copy(), cv2.RETR_CCOMP, cv2.CHAIN_APPROX_TC89_L1)
print len(contours)
centres = []
for i in range(len(contours)):
moments = cv2.moments(contours[i])
centres.append((int(moments['m10']/moments['m00']), int(moments['m01']/moments['m00'])))
cv2.circle(img, centres[-1], 3, (0, 0, 0), -1)
print centres
cv2.imshow('image', img)
cv2.imwrite('output.png',img)
cv2.waitKey(0)
这给了我 4 个中心:
[(474, 411), (96, 345), (58, 214), (396, 145)]
这里要做的显而易见的事情是还要检查轮廓的面积,如果它占图像的百分比太小,请不要将其视为真正的轮廓,它只会是噪声。只需在 for 循环的顶部添加如下内容:
if cv2.contourArea(contours[i]) < 100:
continue
对于 findContours
中的 return 值,我不确定第一个值是什么,因为它不存在于 C++ 版本的 OpenCV(我使用的是)中。第二个值显然只是轮廓(数组的数组),第三个值是包含轮廓嵌套信息的层次结构,这非常方便。
我正在尝试构建一个简单的图像分析工具,该工具将找到适合颜色范围的项目,然后找到所述对象的中心。
例如,在蒙版之后,我正在分析这样的图像:
到目前为止我在代码方面所做的事情相当简单:
import cv2
import numpy
bound = 30
inc = numpy.array([225,225,225])
lower = inc - bound
upper = inc + bound
img = cv2.imread("input.tiff")
cv2.imshow("Original", img)
mask = cv2.inRange(img, lower, upper)
cv2.imshow("Range", mask)
contours = cv2.findContours(mask, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_TC89_L1)
print contours
然而,这给了我无数的轮廓。看the corresponding manpage的时候有些不知所措。能否利用矩合理分析轮廓?轮廓甚至是正确的工具吗?
我发现 this question,它模糊地涵盖了寻找一个对象的中心,但是当有多个项目时我该如何修改这种方法?
如何找到图像中对象的中心?例如,在上面的示例图像中,我正在寻找三个点(矩形和两个圆的中心)。
您可以在轮廓上使用 opencv minEnclosingCircle()
函数来获取每个对象的中心。
查看这个用 C++ 编写的示例,但您可以调整逻辑 Example
尝试print len(contours)
。这将为您提供预期的答案。您看到的输出是轮廓的完整表示,可能有数千个点。
试试这个代码:
import cv2
import numpy
img = cv2.imread('inp.png', 0)
_, contours, _ = cv2.findContours(img.copy(), cv2.RETR_CCOMP, cv2.CHAIN_APPROX_TC89_L1)
print len(contours)
centres = []
for i in range(len(contours)):
moments = cv2.moments(contours[i])
centres.append((int(moments['m10']/moments['m00']), int(moments['m01']/moments['m00'])))
cv2.circle(img, centres[-1], 3, (0, 0, 0), -1)
print centres
cv2.imshow('image', img)
cv2.imwrite('output.png',img)
cv2.waitKey(0)
这给了我 4 个中心:
[(474, 411), (96, 345), (58, 214), (396, 145)]
这里要做的显而易见的事情是还要检查轮廓的面积,如果它占图像的百分比太小,请不要将其视为真正的轮廓,它只会是噪声。只需在 for 循环的顶部添加如下内容:
if cv2.contourArea(contours[i]) < 100:
continue
对于 findContours
中的 return 值,我不确定第一个值是什么,因为它不存在于 C++ 版本的 OpenCV(我使用的是)中。第二个值显然只是轮廓(数组的数组),第三个值是包含轮廓嵌套信息的层次结构,这非常方便。