如何在OpenCV视频流中获取白色像素的平均位置
解决白色像素平均位置绘制稳定圆形的问题
原代码的核心问题
- 直接在原始RGB帧中判断纯
[255,255,255]像素,没用到已经生成的HSV mask,导致白色区域检测不准确(mask过滤后的白色未必是纯RGB255)。 coord_of_white函数循环第一个像素就返回,只在单个白色像素上画圆,帧刷新时圆会在不同像素间跳动。
修复后的完整代码
import cv2 import numpy as np URL = "http://192.168.1.104:81/stream" cap = cv2.VideoCapture(URL) def get_white_mask(frame): # 生成白色区域的mask sensitivity = 20 hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) lower_white = np.array([0, 0, 255 - sensitivity]) upper_white = np.array([255, sensitivity, 255]) mask = cv2.inRange(hsv, lower_white, upper_white) return mask def draw_average_circle(frame, mask): # 从mask中提取所有白色像素的坐标 y_coords, x_coords = np.where(mask == 255) if len(x_coords) == 0 or len(y_coords) == 0: # 无白色像素时直接返回原帧 return frame # 计算所有白色像素的平均坐标 avg_x = int(np.mean(x_coords)) avg_y = int(np.mean(y_coords)) # 在平均位置绘制圆形 return cv2.circle(frame, (avg_x, avg_y), 20, (0, 0, 255), thickness=2) while True: if cap.isOpened(): ret, frame = cap.read() if not ret: break # 获取白色区域mask white_mask = get_white_mask(frame) # 绘制平均位置的稳定圆形 frame_with_circle = draw_average_circle(frame, white_mask) # 生成mask预览图 mask_result = cv2.bitwise_and(frame, frame, mask=white_mask) cv2.imshow("ESP32 CAM", cv2.flip(frame_with_circle, 0)) cv2.imshow("ESP32 CAM MASK", cv2.flip(mask_result, 0)) if cv2.waitKey(1) == ord("q"): break cv2.destroyAllWindows() cap.release()
关键改动说明
- 将mask生成逻辑封装为独立函数,避免依赖全局变量,代码更健壮。
- 改用mask获取白色像素坐标(
np.where(mask == 255)),比判断原始RGB更准确,完全匹配你设置的HSV白色范围。 - 计算所有白色像素的X、Y平均值,让圆形稳定在白色区域的中心位置。
- 增加无白色像素的判断,避免空数组求均值引发报错。
内容的提问来源于stack exchange,提问作者Ramin Moradi
相关产品推荐
相关产品推荐

