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

OpenCV输液滴速检测程序遇IndexError:轴1索引越界问题求助

问题描述

我开发了一个基于OpenCV的输液滴液流速检测程序,核心逻辑是通过圆形检测识别滴液腔中的下落液滴,统计每分钟液滴数量来计算流速。代码参考YouTube视频并结合ChatGPT生成,还设置了ROI(感兴趣区域)优化检测效果。

目前程序在执行chosen[:, 0] += ROI_X和chosen[:, 1] += ROI_Y时触发IndexError:index 1 is out of bounds for axis 1 with size 1,运行时输出的circles数组为[[100],[0],[0],[0]]。试过网上的修复方案,也咨询过计算机专业的朋友,但都没解决问题,附上完整代码求助。


问题分析

从异常的circles数组结构[[100],[0],[0],[0]]可以看出,你的圆形检测返回数据的维度完全不符合OpenCVHoughCircles的规范——正常情况下该函数返回的是(1, N, 3)形状的数组(N为检测到的圆数量,每个圆包含x坐标、y坐标、半径三个参数),但当前数组是(4,1),说明要么是对HoughCircles返回值的处理逻辑错误,要么是检测参数设置不合理导致返回了无效数据,最终导致后续提取x、y坐标时找不到第1轴的元素(即y坐标)。


修复步骤

1. 修正HoughCircles返回值的处理逻辑

OpenCV的HoughCircles返回None或3维数组,必须先判断是否检测到圆,再调整数组维度:

circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, dp=1.2, minDist=50,
                           param1=50, param2=30, minRadius=5, maxRadius=30)
if circles is not None:
    # 转换为整数坐标并调整维度为(N,3)
    circles = np.uint16(np.around(circles))
    circles = circles[0, :]
else:
    # 无检测结果时跳过后续逻辑
    continue

2. 添加坐标转换前的格式校验

在执行ROI坐标转换前,确保chosen数组至少包含x、y两列数据:

chosen = np.array(chosen)
# 校验数组格式是否符合要求
if chosen.size > 0 and chosen.shape[1] >= 2:
    chosen[:, 0] += ROI_X
    chosen[:, 1] += ROI_Y
else:
    print("检测到的圆数据格式异常,无法转换ROI坐标")
    continue

3. 优化圆形检测参数

当前异常的circles数组大概率是检测参数不合理导致的误检,建议调整以下参数:

  • 增大minDist:避免检测到过于接近的重复圆
  • 提高param2(累加器阈值):过滤掉低置信度的假圆
  • 缩小minRadius和maxRadius范围:匹配实际液滴的尺寸

修正后的完整代码示例
import cv2
import numpy as np

# ROI区域参数(根据实际场景调整)
ROI_X = 100
ROI_Y = 50
ROI_W = 200
ROI_H = 300

cap = cv2.VideoCapture(0)
drop_count = 0
start_time = cv2.getTickCount()

while True:
    ret, frame = cap.read()
    if not ret:
        break

    # 提取ROI区域并预处理
    roi = frame[ROI_Y:ROI_Y+ROI_H, ROI_X:ROI_X+ROI_W]
    gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
    gray = cv2.medianBlur(gray, 5)

    # 圆形检测
    circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, dp=1.2, minDist=50,
                               param1=50, param2=30, minRadius=5, maxRadius=30)

    if circles is not None:
        circles = np.uint16(np.around(circles))
        circles = circles[0, :]

        # 筛选符合尺寸的有效圆
        chosen = [circle for circle in circles if 10 <= circle[2] <= 25]
        chosen = np.array(chosen)

        if chosen.size > 0 and chosen.shape[1] >= 2:
            # 转换回原图像坐标
            chosen[:, 0] += ROI_X
            chosen[:, 1] += ROI_Y

            # 绘制检测结果
            for (x, y, r) in chosen:
                cv2.circle(frame, (x, y), r, (0, 255, 0), 2)
                cv2.circle(frame, (x, y), 2, (0, 0, 255), 3)

            # 统计液滴数量(可根据需求添加去重/跟踪逻辑)
            drop_count += len(chosen)

    # 计算每分钟流速
    elapsed_time = (cv2.getTickCount() - start_time) / cv2.getTickFrequency()
    if elapsed_time >= 60:
        flow_rate = drop_count / elapsed_time * 60
        print(f"每分钟流速:{flow_rate:.2f} 滴")
        drop_count = 0
        start_time = cv2.getTickCount()

    cv2.imshow("Drop Detection", frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 16:54:59