如何按邻近度分组图像掩码坐标数组,提取单位置唯一坐标?
问题:提取掩码区域独立坐标以实现自动点击
我正在开发一个程序,用于读取图像、掩码特定颜色(本次目标为棕色)并获取掩码区域的坐标,最终让鼠标移动至这些坐标并执行点击操作。以下是我已完成的代码:
import pyautogui as pygui import cv2 import numpy as np # 读取图像 image = cv2.imread("bloodweb.png") # 定义BGR颜色范围(棕色) lower_brown = np.array([29, 39, 52], dtype="uint8") upper_brown = np.array([33, 44, 60], dtype="uint8") # 创建二值掩码 mask = cv2.inRange(image, lower_brown, upper_brown) # 生成掩码后的图像 output = cv2.bitwise_and(image, image, mask=mask) # 保存掩码图像 cv2.imwrite("bloodweb_mask.png", output) # 读取掩码图像并转为灰度图 img = cv2.imread("bloodweb_mask.png") img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) img = img.astype(np.uint8) # 获取掩码区域的所有非零坐标 coord = cv2.findNonZero(img)
目前通过cv2.findNonZero得到了大量彼此邻近的坐标,我希望每个独立的掩码区域仅保留一个坐标,方便后续鼠标移动至该位置并点击。
原始图像:
掩码图像:
解决方法:通过轮廓检测提取独立区域中心坐标
你可以利用OpenCV的轮廓检测功能,找出每个独立的棕色区域,然后计算每个区域的中心坐标,这样就能为每个区域得到唯一的点击坐标。同时可以优化代码流程,避免重复读写图像。
优化后的代码如下:
import pyautogui as pygui import cv2 import numpy as np # 读取图像 image = cv2.imread("bloodweb.png") # 定义BGR颜色范围(棕色) lower_brown = np.array([29, 39, 52], dtype="uint8") upper_brown = np.array([33, 44, 60], dtype="uint8") # 创建二值掩码 mask = cv2.inRange(image, lower_brown, upper_brown) # 查找轮廓(只检测最外层轮廓) contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 存储每个区域的中心坐标 click_coords = [] for contour in contours: # 计算轮廓的外接矩形 x, y, w, h = cv2.boundingRect(contour) # 计算中心坐标(外接矩形中心足够满足点击需求) center_x = x + w // 2 center_y = y + h // 2 click_coords.append((center_x, center_y)) # 测试:打印所有独立区域的中心坐标 for idx, (x, y) in enumerate(click_coords): print(f"区域{idx+1}的点击坐标:({x}, {y})") # 后续可执行鼠标点击操作 # for x, y in click_coords: # pygui.moveTo(x, y) # pygui.click()
关键说明:
cv2.findContours使用cv2.RETR_EXTERNAL只提取最外层轮廓,避免嵌套轮廓干扰;cv2.CHAIN_APPROX_SIMPLE压缩轮廓点,减少计算量。- 通过
cv2.boundingRect获取轮廓的外接矩形,直接计算矩形中心作为点击坐标,简单高效,完全满足自动点击的需求。 - 去掉了重复读写掩码图像的步骤,直接基于原始mask处理,提升代码效率。
内容的提问来源于stack exchange,提问作者Aaron Lopes
相关产品推荐
相关产品推荐

