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

如何用Python为图像单一绿色区域绘制矩形轮廓并裁剪?

问题描述

我尝试为图像中的亮绿色区域绘制矩形轮廓,但目前仅能绘制出最大矩形,无法针对性地识别单一颜色区域进行绘制。期望得到亮绿色区域的矩形裁剪图。我的代码如下:

import cv2
import numpy as np
median = cv2.imread("try.png", 0)
image_gray = median
image_gray = np.where(image_gray > 30, 255, image_gray)
image_gray = np.where(image_gray <= 30, 0, image_gray)
image_gray = cv2.adaptiveThreshold(image_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 115, 1)
_, contours, _ = cv2.findContours(image_gray, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
rect_cnts = []
for cnt in contours:
    peri = cv2.arcLength(cnt, True)
    approx = cv2.approxPolyDP(cnt, 0.04 * peri, True)
    (x, y, w, h) = cv2.boundingRect(cnt)
    ar = w / float(h)
    if len(approx) == 4: # shape filtering condition
        rect_cnts.append(cnt)
max_area = 0
football_square = None
for cnt in rect_cnts:
    (x, y, w, h) = cv2.boundingRect(cnt)
    if max_area < w*h:
        max_area = w*h
        football_square = cnt
# Draw the result
image = cv2.cvtColor(image_gray, cv2.COLOR_GRAY2RGB)
cv2.drawContours(image, [football_square], -1, (0, 0,255), 5)
cv2.imshow("Result Preview", image)
cv2.waitKey()

解决方案

嗨,这个问题的核心是你当前的代码完全在灰度空间处理,根本没用到颜色信息来锁定亮绿色区域——这就是为什么只会找到画面里的最大矩形,而非你要的绿色区域。咱们换个思路,先通过颜色分割把亮绿色区域单独提取出来,再针对性找轮廓和矩形,具体操作如下:

关键思路拆解

  1. 切换到HSV颜色空间做颜色分割
    RGB空间对光照变化太敏感,HSV空间更适合精准筛选特定颜色。我们可以先定义亮绿色的HSV范围,生成掩码把绿色区域单独抠出来。
  2. 用形态学操作优化掩码
    初始提取的掩码可能有小噪点,用「开运算」(腐蚀+膨胀)可以去掉这些干扰,让轮廓更清晰。
  3. 筛选矩形轮廓并处理
    复用你原来的矩形筛选逻辑,但这次是基于绿色掩码的轮廓,所以只会针对绿色区域工作。

修改后的完整代码

import cv2
import numpy as np

# 读取原始彩色图像(别再读成灰度图了!)
image = cv2.imread("try.png")
# 转换到HSV颜色空间,方便颜色分割
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

# 定义亮绿色的HSV范围(可以根据你的实际图像调整数值)
lower_green = np.array([40, 40, 40])
upper_green = np.array([80, 255, 255])

# 生成绿色区域的掩码:只保留绿色部分
mask = cv2.inRange(hsv, lower_green, upper_green)

# 形态学开运算:去除小噪点,让轮廓更规整
kernel = np.ones((5,5), np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)

# 寻找轮廓:只找最外层轮廓,减少干扰
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 筛选符合条件的绿色矩形轮廓
green_rects = []
for cnt in contours:
    # 计算轮廓周长,用于多边形逼近
    peri = cv2.arcLength(cnt, True)
    # 多边形逼近,把轮廓简化成近似形状
    approx = cv2.approxPolyDP(cnt, 0.04 * peri, True)
    # 获取轮廓的边界矩形
    x, y, w, h = cv2.boundingRect(cnt)
    # 计算宽高比,过滤掉形状不符合的区域(比如细长条)
    ar = w / float(h)
    # 筛选条件:是矩形(4个顶点)、面积足够大、宽高比接近屏幕的比例
    if len(approx) == 4 and w*h > 1000 and 0.8 < ar < 1.2:
        green_rects.append((x, y, w, h))

# 绘制矩形轮廓并裁剪绿色区域
result = image.copy()
for (x, y, w, h) in green_rects:
    # 在原图上绘制红色矩形轮廓
    cv2.rectangle(result, (x, y), (x+w, y+h), (0, 0, 255), 5)
    # 裁剪出绿色区域并显示
    cropped_area = image[y:y+h, x:x+w]
    cv2.imshow(f"Cropped Green Screen", cropped_area)

# 显示最终结果
cv2.imshow("Green Screen with Rectangles", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

注意事项

  • 调整HSV范围:如果你的亮绿色和代码里的范围不匹配,可以用HSV颜色拾取工具(比如OpenCV自带的调色板工具)来获取准确的上下限数值。
  • 调整筛选阈值:代码里的面积阈值(1000)和宽高比范围(0.8-1.2)可以根据你的实际需求修改,过滤掉太小或形状不对的区域。
  • 单一区域处理:如果图像里有多个绿色矩形,但你只需要其中一个,可以在green_rects里做进一步筛选(比如找面积最大的,或者位置最符合的)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:51:29