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

如何用OpenCV检测相互交叠的独立矩形并获取其坐标?

问题描述

需要检测屏幕上随机出现的多个矩形坐标,已知矩形宽度,但用轮廓法检测宽度存在误差。当前代码只能检测到整个矩形块,无法识别出独立的3个矩形,希望获取每个矩形的准确坐标。

现有实时检测代码:

yellow = (5,242,206)
while True:
 isFrameValid, frame = capture.read()

 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
 roi = gray [0:300, 0:1920]

 threshold, thresh_image = cv2.threshold(roi, 30, 255, cv2.THRESH_BINARY)

 # 查找轮廓
 contours, _ =cv2.findContours(thresh_image,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
 cv2.drawContours(frame, contours, -1,yellow,1) 

问题复现代码:

import cv2

img= cv2.imread('./IwOXW.png')

yellow = (5,242,206)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
roi = gray [0:300, 0:1920]

threshold, thresh_image = cv2.threshold(roi, 30, 255, cv2.THRESH_BINARY)

# 查找轮廓
contours, _ = cv2.findContours(thresh_image,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img, contours, -1,yellow,1) 

cv2.imshow('Frame',img)
cv2.waitKey(0)  

示例图片说明:画面中有3个垂直排列的深色矩形,位于浅色背景上,矩形之间存在细小的间隙。

解决方案

1. 替换固定阈值为自适应阈值

固定阈值容易受全局明暗影响,导致矩形间的背景被误判为前景,使轮廓粘连。改用自适应阈值能根据局部区域调整阈值,更精准分离前景和背景:

# 替换原固定阈值代码
thresh_image = cv2.adaptiveThreshold(
    roi, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2
)

使用THRESH_BINARY_INV是因为目标矩形为深色,反转后矩形变为白色前景,更便于轮廓检测。

2. 形态学开运算分离粘连轮廓

若阈值调整后仍有轮廓粘连,用开运算(先腐蚀再膨胀)断开连通区域,参数可根据矩形间隙大小调整:

import numpy as np

# 定义结构元素,尺寸根据实际间隙调整
kernel = np.ones((3, 3), np.uint8)
# 开运算分离粘连
thresh_image = cv2.morphologyEx(thresh_image, cv2.MORPH_OPEN, kernel)

3. 基于已知尺寸筛选目标轮廓

利用已知的矩形宽度(及高度)范围,过滤掉不符合的干扰轮廓,确保只保留目标矩形:

# 遍历所有轮廓,筛选符合尺寸的矩形
for cnt in contours:
    x, y, w, h = cv2.boundingRect(cnt)
    # 替换为你实际的宽度、高度范围
    w_min, w_max = 45, 55
    h_min, h_max = 190, 210
    if w_min < w < w_max and h_min < h < h_max:
        # 绘制矩形并打印坐标
        cv2.rectangle(img, (x, y), (x + w, y + h), yellow, 2)
        print(f"矩形坐标:左上角({x}, {y}),右下角({x+w}, {y+h})")

完整优化后的复现代码

import cv2
import numpy as np

img = cv2.imread('./IwOXW.png')
yellow = (5,242,206)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
roi = gray[0:300, 0:1920]

# 自适应阈值处理
thresh_image = cv2.adaptiveThreshold(
    roi, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2
)

# 形态学开运算分离粘连轮廓
kernel = np.ones((3, 3), np.uint8)
thresh_image = cv2.morphologyEx(thresh_image, cv2.MORPH_OPEN, kernel)

# 查找轮廓
contours, _ = cv2.findContours(thresh_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 筛选并标记目标矩形
for cnt in contours:
    x, y, w, h = cv2.boundingRect(cnt)
    # 根据实际尺寸调整范围
    if 45 < w < 55 and 190 < h < 210:
        cv2.rectangle(img, (x, y), (x + w, y + h), yellow, 2)
        print(f"矩形坐标:左上角({x}, {y}),右下角({x+w}, {y+h})")

cv2.imshow('Frame', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 04:55:18