问题描述
代码可以识别指定颜色的两个轮廓,但是我不知道如何分别保存每个轮廓的坐标(X,Y)。
尽管坐标出现在框架中,但是在打印位置变量时,它仅保存两个坐标之一。
有人知道我如何使用cv.moments单独找到每个轮廓的矩,或者有另一个想法来实现预期的目标吗?
for c_2 in contour_2:
area = cv2.contourArea(c_2)
# Noise reduction using area as parameter
if area > 2000:
M_1 = cv2.moments(c_2)
# Centroid
if M_1["m00"] == 0: M_1["m00","m01"] = 1
x_2 = int(M_1["m10"] / M_1["m00"])
y_2 = int(M_1["m01"] / M_1["m00"])
cv2.circle(frame,(x_2,y_2),7,(0,255,0),-1)
font = cv2.FONT_HERShey_SIMPLEX
cv2.putText(frame,'{},{}'.format(x_2,(x_2 + 10,font,0.75,1,cv2.LINE_AA)
# Contour smoothing
newContour = cv2.convexHull(c)
cv2.drawContours(frame,[newContour],(255,3)´´´
解决方法
findContours
函数的输出是一个轮廓列表。这意味着您可以像已经在做的那样循环遍历它,并且在这样做时,将您想要的每个轮廓的任何值保存在您选择的数据结构中。您当前的代码仅保存一组坐标,因为每次使用轮廓运行循环时都会更新坐标。
存储所有值的一种方法是为每个轮廓的每个测量值创建单独的列表:
# Initialize the empty lists for each measurement
areas = []
centers = []
moments_list = []
# loop through all contours,calculate measurements and store values in appropriate list
for c in contours:
areas.append(cv2.contourArea(c))
M_1= cv2.moments(c)
moments_list.append(M_1)
if M_1["m00"] == 0: M_1["m00","m01"] = 1
x = int(M_1["m10"] / M_1["m00"])
y = int(M_1["m01"] / M_1["m00"])
centers.append((x,y))
然后您可以使用索引访问每个轮廓的测量值,并将这些值用于后续操作,例如,打印给定轮廓的测量值:
i = 0
print(f"Contour {i} measurements: area= areas[i],center= centers[i],moments= moments_list[i]")
示例输出:
>>> Contour 0 measurements: area= 1111,center= (123,345),moments= {...}
获得所有测量值后,您可以使用列表构建数据框,以很好地组织值。 字典也是一种选择,将数据保存为键组合:
contours_dict = {0: {'area': 1111,'center': (123,'moments': {...},...},1: {'area': 2222,'center': (234,567),2: {'area': 3333,'center': (345,678),...}
这更接近于数据帧结构,无需使用外部库。