如何在Python中高效检测连续5个以上指定颜色的像素?
优化方案:实时计数连续匹配像素,提前终止遍历
核心思路是不用存储所有符合条件的像素序号,而是在遍历像素的过程中实时统计连续匹配indianred的像素数量,一旦连续数达到5就立即返回True,遍历结束后如果从未达到则返回False。这种方法能减少内存占用,还能提前终止循环,大幅提升效率。
具体实现步骤
- 遍历裁剪后的图像像素时,维护一个
current_streak变量,初始值为0 - 对每个像素:
- 直接读取OpenCV返回的BGR格式像素值
- 通过
webcolors匹配最接近的颜色名称 - 如果匹配结果是
indianred,current_streak += 1,随即检查是否≥5,是则直接返回True - 如果不是目标颜色,将
current_streak重置为0
- 遍历完所有像素后,返回
False
代码示例
import cv2 import webcolors def has_continuous_indianred(cropped_img, target_color="indianred"): current_streak = 0 # 转换目标颜色为BGR格式(webcolors默认用RGB) target_rgb = webcolors.name_to_rgb(target_color) target_bgr = (target_rgb[2], target_rgb[1], target_rgb[0]) # 遍历裁剪区域的每个像素 for y in range(cropped_img.shape[0]): for x in range(cropped_img.shape[1]): pixel_bgr = cropped_img[y, x] # 匹配颜色名称,无精确匹配时取最接近的 try: matched_color = webcolors.rgb_to_name((pixel_bgr[2], pixel_bgr[1], pixel_bgr[0])) except ValueError: matched_color = webcolors.rgb_to_name(webcolors.closest_color((pixel_bgr[2], pixel_bgr[1], pixel_bgr[0]))[0]) if matched_color == target_color: current_streak += 1 if current_streak >= 5: return True else: current_streak = 0 return False # 调用示例 img = cv2.imread("your_image.jpg") cropped_area = img[100:300, 100:300] # 自定义裁剪范围 result = has_continuous_indianred(cropped_area) print(result)
额外提速优化
如果不需要严格匹配颜色名称,可跳过webcolors的字符串匹配逻辑,直接通过颜色差值判断像素是否属于目标色系,速度会快很多:
import cv2 # 预定义indianred的BGR值(对应RGB(192,107,92)) INDIANRED_BGR = (92, 107, 192) COLOR_DIFF_THRESHOLD = 15 # 颜色相似度阈值,可根据需求调整 def has_continuous_indianred_fast(cropped_img): current_streak = 0 for y in range(cropped_img.shape[0]): for x in range(cropped_img.shape[1]): b, g, r = cropped_img[y, x] # 用曼哈顿距离计算颜色差值 color_diff = abs(b - INDIANRED_BGR[0]) + abs(g - INDIANRED_BGR[1]) + abs(r - INDIANRED_BGR[2]) if color_diff <= COLOR_DIFF_THRESHOLD: current_streak += 1 if current_streak >= 5: return True else: current_streak = 0 return False
内容的提问来源于stack exchange,提问作者S Andrew
相关产品推荐
相关产品推荐

