如何使用OpenCV Python检测位掩码中目标对象的最高点
解决方法
现有代码核心错误
has_white = print(np.any(draw_img, axis=1))写法错误,print函数返回值为None,后续对has_white的计算全部无效- np.any调用时维度参数设置错误,没有先合并通道维度判断单像素是否属于目标
实现逻辑
- 从二值掩码中提取最大目标轮廓,生成单通道的纯净掩码(避免三通道判断的冗余)
- 从上到下逐行扫描掩码,第一个存在非零像素的行就是最高点所在的y坐标
- 在该行中提取所有非零像素的x坐标,取中间值(或自定义规则取值)即为最高点的x坐标
修正后完整代码
import cv2 import numpy as np path = 'test.jpg' # 替换为你本地的原始图像路径 img = cv2.imread(path) img = cv2.resize(img, (640, 480)) org_img = img.copy() show_img = img.copy() # 掩码生成逻辑和原有逻辑一致 img_blur = cv2.blur(img,(5,5)) imgHSV = cv2.cvtColor(img_blur, cv2.COLOR_BGR2HSV) lower = np.array([0, 0, 48]) upper = np.array([179, 255, 166]) mask = cv2.inRange(imgHSV, lower, upper) # 提取最大轮廓 cont, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) c = max(cont, key=cv2.contourArea) # 生成单通道纯净掩码 single_mask = np.zeros(mask.shape, dtype=np.uint8) cv2.drawContours(single_mask, [c], -1, 255, thickness=-1) # 裁剪上下margin,和原有逻辑一致 margin = 90 single_mask_crop = single_mask[margin:-margin] show_img_crop = show_img[margin:-margin] # 查找最高点:先找第一个有非零值的行(y坐标) row_has_target = np.any(single_mask_crop == 255, axis=1) top_y = np.argmax(row_has_target) # argmax会返回第一个True的索引,就是最靠上的行 # 在该行找所有目标像素的x坐标 top_x_list = np.where(single_mask_crop[top_y] == 255)[0] # 取中间值作为最高点的x,可根据需求修改为取最左/最右值 top_x = int(np.mean(top_x_list)) # 最高点坐标换算回原图(因为裁剪了margin,所以y坐标要加margin偏移) origin_top_y = top_y + margin origin_top_x = top_x print(f"目标最高点坐标:x={origin_top_x}, y={origin_top_y}") # 可视化标记最高点 cv2.circle(show_img, (origin_top_x, origin_top_y), 5, (0,0,255), -1) cv2.circle(show_img_crop, (top_x, top_y), 5, (0,0,255), -1) # 显示结果 cv2.imshow("原始图标记最高点", show_img) cv2.imshow("裁剪后图标记最高点", show_img_crop) cv2.imshow("掩码", single_mask) k = cv2.waitKey(0) if k == 27: cv2.destroyAllWindows()
内容的提问来源于stack exchange,提问作者user15852742
相关产品推荐
相关产品推荐

