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

基于cv2的形状识别代码在特定图片上失效的问题求助

问题排查与修复方案

针对你提供的形状识别代码在指定图片上失效的问题,核心原因是预处理流程错误和轮廓检测逻辑混乱,以下是具体修复方案:

1. 原代码的关键问题点

  • 错误地对灰度图执行膨胀操作,而非二值化后的图像,导致mask生成完全偏离预期
  • 手动创建mask的逻辑冗余且错误,无法有效分离前景与背景
  • 定义了detect_shape函数却未实际调用,重复编写形状判断逻辑
  • 未利用输入的num_shapes参数做校验,也未实现“输出形状类型数量”的需求

2. 修复后的完整代码

import cv2
import numpy as np

def detect_shape(cnt):
    peri = cv2.arcLength(cnt, True)
    # 调整epsilon参数为0.02,适配圆形的轮廓近似
    vertices = cv2.approxPolyDP(cnt, 0.02 * peri, True)
    if len(vertices) == 3:
        return "Triangle"
    elif len(vertices) == 4:
        x, y, w, h = cv2.boundingRect(vertices)
        aspect_ratio = float(w) / h
        if 0.95 <= aspect_ratio <= 1.05:
            return "Square"
        else:
            return "Rectangle"
    else:
        return "Circle"

# 读取输入
num_shapes = int(input("Enter the number of shapes in the image: "))
image_path = input("Enter the path to the image: ")

# 读取图像并预处理
image = cv2.imread(image_path)
if image is None:
    print("Error: 无法读取图片,请检查路径是否正确")
    exit()

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 高斯模糊降噪,避免小干扰点影响轮廓检测
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# 自适应二值化,适配不同光照下的前景背景分离
binary = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)

# 轮廓检测
contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 筛选有效轮廓:面积过滤+数量校验(匹配输入的num_shapes)
filtered_contours = []
for cnt in contours:
    area = cv2.contourArea(cnt)
    # 根据图片中形状大小调整面积阈值,适配目标图片的圆形大小
    if 500 < area < 5000:
        filtered_contours.append(cnt)

# 校验轮廓数量与输入的形状总数是否匹配
if len(filtered_contours) != num_shapes:
    print(f"警告:检测到{len(filtered_contours)}个形状,与输入的{num_shapes}个不符")

# 统计形状类型
shape_types = set()
for contour in filtered_contours:
    shape = detect_shape(contour)
    shape_types.add(shape)
    # 在图像上标注形状
    M = cv2.moments(contour)
    if M["m00"] != 0:
        cx = int(M["m10"] / M["m00"])
        cy = int(M["m01"] / M["m00"])
        cv2.putText(image, shape, (cx-30, cy), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

# 输出形状类型数量(符合需求:全同类型则输出1)
print(f"形状类型数量:{len(shape_types)}")
print("各形状统计:")
shape_count = {t: 0 for t in shape_types}
for cnt in filtered_contours:
    shape_count[detect_shape(cnt)] += 1
for t, count in shape_count.items():
    print(f"{t}: {count}")

# 显示结果
cv2.imshow('Shape Detection Result', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

3. 修复说明

  • 预处理优化:改用高斯模糊降噪+自适应二值化,能更鲁棒地分离图片中的蓝色圆形与白色背景
  • 轮廓筛选:增加面积范围过滤,排除过小的干扰轮廓;同时校验检测到的轮廓数量与输入的num_shapes
  • 形状判断优化:调整approxPolyDP的epsilon参数为0.02,更准确识别圆形(原0.04会导致圆形被误判为多边形)
  • 实现需求功能:通过集合shape_types统计不同形状的数量,最终输出类型总数
  • 代码简化:复用detect_shape函数,消除冗余逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 10:32:28