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

如何使用OpenCV与Python检测图像中的白色区域?

解决盘子中大型白色区域的坐标提取问题

你的预处理流程(放大、灰度转换、形态学闭运算填充孔洞、OTSU二值化)已经为后续的区域检测打下了不错的基础,轮廓检测效果不理想大概率是因为没有对检测到的轮廓做针对性筛选,或者可以换用连通区域分析的方法来更精准地定位大型白色区域。

方法一:优化轮廓检测与筛选

既然已经得到了二值化后的light图像,我们可以通过轮廓检测结合面积、形状筛选来锁定目标区域:

import cv2
import numpy as np
import imutils

original = cv2.imread("Plates\24.png")
original = cv2.resize(original, None, fx=3, fy=3, interpolation=cv2.INTER_CUBIC)
gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY)

# 形态学闭运算填充孔洞
squareKern = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
light = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, squareKern)
# OTSU二值化
light = cv2.threshold(light, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

# 检测轮廓,只保留最外层轮廓避免干扰
cnts = cv2.findContours(light.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)

# 筛选大型白色区域:根据实际场景调整面积阈值
large_white_regions = []
for c in cnts:
    area = cv2.contourArea(c)
    # 假设最小有效面积是1000像素(根据你的图像尺寸调整)
    if area > 1000:
        # 获取区域的外接矩形坐标
        x, y, w, h = cv2.boundingRect(c)
        large_white_regions.append((x, y, x+w, y+h))
        # 可选:在原图上绘制矩形验证结果
        cv2.rectangle(original, (x, y), (x+w, y+h), (0, 255, 0), 2)

# 输出大型白色区域的坐标
for idx, coords in enumerate(large_white_regions):
    print(f"大型白色区域 {idx+1} 坐标:左上角({coords[0]}, {coords[1]}),右下角({coords[2]}, {coords[3]})")

# 展示处理后的图像
cv2.imshow("Detected Regions", original)
cv2.waitKey(0)
cv2.destroyAllWindows()

关键优化点:

  • 使用cv2.RETR_EXTERNAL只检测最外层轮廓,避免内部小轮廓干扰
  • 通过cv2.contourArea()过滤掉面积过小的区域,只保留符合"大型"要求的目标
  • 用cv2.boundingRect()获取区域的矩形坐标,方便后续调用使用

方法二:连通区域分析(更精准的区域定位)

如果轮廓筛选还是达不到预期,可以尝试用连通区域分析(cv2.connectedComponentsWithStats),它能直接给出每个连通区域的面积、坐标等统计信息,逻辑更清晰:

import cv2
import numpy as np
import imutils

original = cv2.imread("Plates\24.png")
original = cv2.resize(original, None, fx=3, fy=3, interpolation=cv2.INTER_CUBIC)
gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY)

squareKern = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
light = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, squareKern)
light = cv2.threshold(light, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

# 连通区域分析,8邻域连通
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(light, connectivity=8)

large_white_regions = []
# 跳过标签0(代表背景区域)
for i in range(1, num_labels):
    area = stats[i, cv2.CC_STAT_AREA]
    if area > 1000:  # 根据图像实际尺寸调整面积阈值
        x = stats[i, cv2.CC_STAT_LEFT]
        y = stats[i, cv2.CC_STAT_TOP]
        w = stats[i, cv2.CC_STAT_WIDTH]
        h = stats[i, cv2.CC_STAT_HEIGHT]
        large_white_regions.append((x, y, x+w, y+h))
        cv2.rectangle(original, (x, y), (x+w, y+h), (0, 0, 255), 2)

# 输出大型白色区域的坐标
for idx, coords in enumerate(large_white_regions):
    print(f"大型白色区域 {idx+1} 坐标:左上角({coords[0]}, {coords[1]}),右下角({coords[2]}, {coords[3]})")

cv2.imshow("Connected Components", original)
cv2.waitKey(0)
cv2.destroyAllWindows()

优势:

  • 能区分所有独立的连通区域,不会出现轮廓检测中可能的轮廓嵌套问题
  • 直接提供区域的完整统计信息,筛选逻辑更直观

额外建议:

  • 如果白色区域和盘子边缘粘连,可以先尝试用形态学开运算(cv2.MORPH_OPEN)或者调整闭运算的核大小,分离粘连区域
  • 面积阈值需要根据你放大后的图像实际尺寸调整,可以先打印所有区域的面积,找到合适的临界值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 16:22:33