如何通过OpenCV findContours获取检测轮廓/圆点的中心坐标
问题描述
需要检测尺寸为(3000, 2000, 3)的图像中圆点的(x, y)坐标,输入图像如下:
用户使用以下代码处理图像:
img = cv2.imread(path_dots_data + "01000.exr", cv2.IMREAD_ANYCOLOR |cv2.IMREAD_ANYDEPTH | cv2.IMREAD_UNCHANGED) img = img - dark_img img = img / img.max() img = np.clip(a = img, a_min = 0.0, a_max = 1.0) # Multiply by 255 before converting to uint 8 dtype- img = img * 255.0 # Convert to uint8 dtype for opencv2 algos to work- img = img.astype('uint8') # Apply blurring to suppress high-frequency signals- blur = cv2.medianBlur(img, 5) # Convert from color to gray-scale- gray = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) # Apply thresholding to detect white dots on black background- thresh = cv2.threshold(gray * 5, 200, 255, cv2.THRESH_BINARY)[1] # Apply findCountours()- cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[0] if len(cnts) == 2 else cnts[1] len(cnts) # 41 # Add circles around detected contours- min_area = 0.1 white_dots = [] for c in cnts: area = cv2.contourArea(c) if area > min_area: cv2.drawContours(img, [c], -1, (36, 255, 12), 2) white_dots.append(c) # The final output looks like: plt.figure(figsize = (12, 10)) plt.imshow(img, cmap = 'gray') plt.show()
处理后的输出图像如下:
用户的问题:如何获取输出图像中绿色线条标注的轮廓/圆点的中心(x, y)坐标?
解决方案
可以通过两种实用方法获取轮廓的中心坐标:
方法一:利用轮廓矩计算中心
OpenCV的cv2.moments()函数可计算轮廓的矩,通过矩的数值推导中心坐标。修改原有循环代码如下:
min_area = 0.1 white_dots = [] dot_centers = [] # 存储所有圆点中心坐标 for c in cnts: area = cv2.contourArea(c) if area > min_area: cv2.drawContours(img, [c], -1, (36, 255, 12), 2) white_dots.append(c) # 计算轮廓矩 M = cv2.moments(c) # 避免除数为0的异常 if M["m00"] != 0: cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) dot_centers.append((cX, cY)) # 可选:在图像上用红色圆点标注中心 cv2.circle(img, (cX, cY), 5, (0, 0, 255), -1)
执行后,dot_centers列表将保存所有检测到的圆点中心(x, y)坐标。
方法二:通过最小外接圆获取圆心
如果目标圆点接近正圆形,使用cv2.minEnclosingCircle()能直接得到圆心坐标,精度更高:
min_area = 0.1 white_dots = [] dot_centers = [] for c in cnts: area = cv2.contourArea(c) if area > min_area: cv2.drawContours(img, [c], -1, (36, 255, 12), 2) white_dots.append(c) # 获取最小外接圆的圆心与半径 (x, y), radius = cv2.minEnclosingCircle(c) center = (int(x), int(y)) dot_centers.append(center) # 可选:在图像上标注圆心 cv2.circle(img, center, 5, (0, 0, 255), -1)
两种方法均可满足需求,可根据圆点的形状特征选择使用。
内容的提问来源于stack exchange,提问作者Arun
相关产品推荐
相关产品推荐

