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

如何用OpenCV和Python精准检测白色实体内部首个黑色圆圈?

优化OpenCV检测白色实体内部黑色圆圈的方案

原代码存在的问题

  • 拼写错误:imporrt cv2 应为 import cv2
  • 函数eroded_image使用了self参数,但并非类成员方法,调用时会报错
  • 处理流程冗余:用Canny+膨胀腐蚀+自适应阈值的组合,没有针对性利用黑色圆圈的特征,容易引入干扰

优化思路

针对白色实体内部的黑色圆圈这一特征,简化处理流程:

  • 直接通过灰度二值化提取黑色区域
  • 利用轮廓的面积、圆形度筛选目标,或使用霍夫圆检测(更适配圆形目标)
  • 优先定位白色实体内部的第一个符合条件的圆圈

优化后的代码

import cv2
import numpy as np

def detect_inner_black_circle(image_path):
    # 读取图像
    image = cv2.imread(image_path, cv2.IMREAD_COLOR)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    # 1. 二值化提取黑色区域:反转阈值,将黑色圆圈转为白色前景
    _, binary = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY_INV)
    
    # 2. 去除小干扰噪点
    kernel = np.ones((3, 3), np.uint8)
    binary_clean = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel, iterations=1)
    
    # 3. 查找轮廓并筛选目标(利用层级关系判断内部轮廓)
    contours, hierarchy = cv2.findContours(binary_clean, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
    
    target_contour = None
    for i, cnt in enumerate(contours):
        # hierarchy[0][i][3] != -1 表示当前轮廓是外层轮廓(白色实体)的子轮廓
        if hierarchy[0][i][3] != -1:
            # 计算圆形度:值越接近1,轮廓越接近圆形
            area = cv2.contourArea(cnt)
            perimeter = cv2.arcLength(cnt, True)
            if perimeter == 0:
                continue
            circularity = 4 * np.pi * (area / (perimeter ** 2))
            # 筛选圆形度达标的轮廓(可根据实际场景调整阈值)
            if circularity > 0.8:
                target_contour = cnt
                break  # 取第一个符合条件的内部黑色圆圈
    
    # 绘制检测结果
    if target_contour is not None:
        cv2.drawContours(image, [target_contour], -1, (0, 0, 255), 3)
        # 绘制圆心与最小外接圆
        (x, y), radius = cv2.minEnclosingCircle(target_contour)
        center = (int(x), int(y))
        radius = int(radius)
        cv2.circle(image, center, radius, (255, 0, 0), 2)
        cv2.circle(image, center, 2, (0, 255, 0), 3)
    
    return image

# 调用示例
result_image = detect_inner_black_circle('image231.jpg')
cv2.imshow('Detected Circle', result_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

代码说明

  1. 二值化处理:通过反转阈值,将黑色圆圈转为白色前景,便于轮廓识别
  2. 形态学开运算:先腐蚀后膨胀,消除小噪点对检测的干扰
  3. 轮廓层级筛选:使用RETR_CCOMP获取轮廓层级,确保检测的是白色实体内部的轮廓
  4. 圆形度筛选:通过计算轮廓的圆形度,排除非圆形的黑色干扰区域
  5. 结果可视化:绘制轮廓、圆心和外接圆,直观验证检测效果

可选方案:霍夫圆检测

若目标圆圈边缘清晰,可直接使用霍夫圆检测,代码片段如下:

# 在灰度图预处理后添加
blur = cv2.GaussianBlur(gray, (5, 5), 0)
# 调整参数适配实际图像:minDist为圆心最小距离,param1/param2为检测阈值,minRadius/maxRadius限制半径范围
circles = cv2.HoughCircles(blur, cv2.HOUGH_GRADIENT, 1, 20,
                          param1=50, param2=30, minRadius=10, maxRadius=50)
if circles is not None:
    circles = np.uint16(np.around(circles))
    # 取第一个检测到的圆圈
    for i in circles[0, :1]:
        cv2.circle(image, (i[0], i[1]), i[2], (0, 255, 0), 2)
        cv2.circle(image, (i[0], i[1]), 2, (0, 0, 255), 3)

内容的提问来源于stack exchange,提问作者Muhammad Zeeshan Babar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 16:34:53