You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenCV Python检测指定尺寸矩形的问题求助

自定义尺寸矩形检测问题解决方案

问题分析

  1. 被分割矩形无法检测:原代码Canny边缘检测参数存在明显错误(阈值写成了单一数字600900),且缺少形态学预处理,导致断裂的边缘无法被连接,轮廓检测不完整;
  2. 无关检测结果过多:当前过滤条件(len(polygon)<=11、弧长范围100-950)过于宽松,未严格匹配目标矩形的尺寸与宽高比,导致大量非目标轮廓被误检。

解决步骤

  1. 修正Canny参数:设置合理的高低阈值(示例用50/150,可根据实际画面调整);
  2. 添加预处理操作:高斯模糊减少噪声,膨胀操作连接断裂边缘,解决被分割矩形的轮廓断裂问题;
  3. 严格轮廓过滤:
    • 仅保留四边形轮廓(len(polygon)==4);
    • 基于目标尺寸(BOX_WIDTH=235,BOX_HEIGHT=10)设置误差范围,过滤尺寸不符的轮廓;
    • 验证宽高比,目标矩形宽高比约为23.5,进一步筛选符合比例的轮廓。

修改后的代码

import numpy as np
import cv2
from mss import mss
from PIL import Image
import imutils

sct = mss()
BOX_WIDTH = 235
BOX_HEIGHT = 10
# 允许的尺寸误差范围(百分比)
SIZE_TOLERANCE = 0.1

while True:
    w, h = 240, 640
    monitor = {'top': 100, 'left': 900, 'width': w, 'height': h}

    img = Image.frombytes('RGB', (w, h), sct.grab(monitor).rgb)
    image_data = np.asarray(img)

    # 转换为灰度图
    gray = cv2.cvtColor(image_data, cv2.COLOR_BGR2GRAY)
    
    # 高斯模糊减少噪声
    blurred = cv2.GaussianBlur(gray, (5, 5), 0)
    
    # Canny边缘检测(修正参数)
    edges = cv2.Canny(blurred, 50, 150)
    
    # 膨胀操作连接断裂边缘
    kernel = np.ones((3, 3), np.uint8)
    edges = cv2.dilate(edges, kernel, iterations=1)

    # 查找轮廓(使用CHAIN_APPROX_SIMPLE减少轮廓点数量)
    hierarchy = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    contours = imutils.grab_contours(hierarchy)

    for contour in contours:
        # 计算轮廓弧长
        arc_len = cv2.arcLength(contour, True)
        # 轮廓逼近(调整精度参数)
        polygon = cv2.approxPolyDP(contour, 0.02 * arc_len, True)
        
        # 只保留四边形轮廓
        if len(polygon) == 4:
            x, y, cnt_w, cnt_h = cv2.boundingRect(polygon)
            # 计算目标尺寸的误差范围
            min_width = BOX_WIDTH * (1 - SIZE_TOLERANCE)
            max_width = BOX_WIDTH * (1 + SIZE_TOLERANCE)
            min_height = BOX_HEIGHT * (1 - SIZE_TOLERANCE)
            max_height = BOX_HEIGHT * (1 + SIZE_TOLERANCE)
            
            # 匹配目标尺寸和宽高比
            if (min_width <= cnt_w <= max_width) and (min_height <= cnt_h <= max_height):
                aspect_ratio = cnt_w / cnt_h
                # 目标宽高比约为23.5,设置合理范围
                if 20 <= aspect_ratio <= 27:
                    # 绘制检测到的矩形
                    cv2.rectangle(image_data, (x, y), (x + cnt_w, y + cnt_h), (0, 255, 0), 2)

    cv2.imshow('test', image_data)
    if cv2.waitKey(25) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break

额外说明

  • 若被分割矩形仍无法检测,可调整膨胀操作的iterations参数(如改为2),或微调Canny的阈值;
  • 尺寸误差范围(SIZE_TOLERANCE)可根据画面采集精度调整;
  • 宽高比范围可根据目标矩形的实际比例进一步缩小。

内容的提问来源于stack exchange,提问作者Mark_us

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 21:54:54