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

OpenCV椭圆检测过滤非目标形状的判定条件设置

OpenCV目标椭圆检测过滤方案

当前以全图几何中心为基准的区域过滤逻辑失效,可通过分层筛选直接定位对应3个亮区的目标椭圆,无需提前硬编码目标中心坐标。

预过滤规则(先剔除绝大多数无效检测结果)

在做椭圆拟合和匹配前,先对轮廓做第一层筛选,砍掉噪点、边框等无效轮廓:

  • 轮廓点数校验:拟合椭圆要求轮廓点数大于5,不满足的轮廓直接跳过
  • 面积过滤:用cv2.contourArea(cnt)计算轮廓面积,设置上下阈值,剔除面积过小的噪点、面积过大的图像边缘轮廓
  • 椭圆形态过滤:目标椭圆接近正圆,计算椭圆长短轴比值(短轴长度/长轴长度),剔除比值低于0.7的扁长形无效椭圆;同时过滤长/短轴尺寸超出合理范围的椭圆

亮区匹配规则(精准定位3个目标椭圆)

目标椭圆对应图中亮度最高的3个区域,直接通过椭圆覆盖区域的平均亮度做最终筛选:

  1. 对所有通过预过滤的椭圆,创建同尺寸全黑掩码,用cv2.ellipse()将当前椭圆以白色填充到掩码上
  2. 调用cv2.mean(灰度图, mask=掩码)计算当前椭圆覆盖区域的平均灰度值
  3. 将所有椭圆按平均灰度值从高到低排序,取前3个即为目标椭圆

动态中心计算(替代硬编码的全图中心)

如果后续需要用中心区域做二次校验,不需要使用全图几何中心(w/2, h/2),直接计算3个目标椭圆中心坐标的平均值,即可得到3个亮区组成的目标组的实际中心,适配性远高于硬编码坐标。

修正后代码

注:修复了原代码中未定义变量t2的bug,阈值参数可根据实际图像尺寸微调

import cv2
import numpy as np

input_image = cv2.imread('test_image_2.bmp')
gray = cv2.cvtColor(input_image, cv2.COLOR_BGR2GRAY)

thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 101, 0)
h, w = gray.shape

contours, hierarchy = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_TC89_KCOS)
valid_ellipses = []

for cnt in contours:
    if len(cnt) <= 5:
        continue
    # 面积过滤
    area = cv2.contourArea(cnt)
    if area < 100 or area > w*h*0.2:
        continue
    ellipse = cv2.fitEllipse(cnt)
    (x, y), (major_axis, minor_axis), angle = ellipse
    # 规避除零错误
    if minor_axis == 0 or major_axis == 0:
        continue
    # 长短轴比过滤
    axis_ratio = min(major_axis, minor_axis) / max(major_axis, minor_axis)
    if axis_ratio < 0.7:
        continue
    # 尺寸过滤
    if major_axis < 20 or major_axis > 200:
        continue
    # 计算椭圆区域平均亮度
    mask = np.zeros(gray.shape, dtype=np.uint8)
    cv2.ellipse(mask, ellipse, 255, -1)
    mean_bright = cv2.mean(gray, mask=mask)[0]
    valid_ellipses.append( (-mean_bright, ellipse) )

# 按亮度降序取前3个目标
valid_ellipses.sort()
target_ellipses = [item[1] for item in valid_ellipses[:3]]

# 绘制检测结果
for e in target_ellipses:
    cv2.ellipse(input_image, e, (0, 0, 255), 2)

# 可选:绘制3个目标的组中心
if len(target_ellipses) == 3:
    center_x = int(sum(e[0][0] for e in target_ellipses) / 3)
    center_y = int(sum(e[0][1] for e in target_ellipses) / 3)
    cv2.circle(input_image, (center_x, center_y), 10, (255, 255, 0), -1)

cv2.imshow('target_ellipses', input_image)
cv2.waitKey()

相关参考素材

  • 输入图像:输入图像
  • 图像中心标记:图像中心标记
  • 全量椭圆检测结果:全量椭圆检测结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:15:43