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

基于Python OpenCV 4.8检测试管液位的技术求助

试管液位高度检测方案

这两张图虽有模糊,但完全可以通过针对性预处理和检测逻辑实现液位检测,无需直接放弃。以下是基于Python OpenCV 4.8的可行方案:

一、预处理:降噪与对比度增强

原始图的模糊和噪点会直接干扰边缘/轮廓检测,先做预处理优化:

  • 转灰度图:gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  • 高斯模糊降噪:blur = cv2.GaussianBlur(gray, (5,5), 0) 用5×5核过滤高频噪点,保留液位的明暗分界
  • 自适应阈值分割:thresh = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) 自适应阈值能更好应对局部光照差异,突出液位线的对比度

二、两种液位线检测方法

方法1:霍夫直线检测(针对性找水平线)

液位是水平直线,用霍夫变换筛选水平方向的直线:

import cv2
import numpy as np

# 读取图片(替换为你的图片路径)
img = cv2.imread("test_tube.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5,5), 0)
thresh = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)

# Canny边缘检测
edges = cv2.Canny(thresh, 50, 150)
# 霍夫直线检测
lines = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=30, minLineLength=20, maxLineGap=5)

# 筛选接近水平的直线(角度±5度以内)
horizontal_lines = []
if lines is not None:
    for line in lines:
        x1, y1, x2, y2 = line[0]
        angle = np.arctan2(y2 - y1, x2 - x1) * 180 / np.pi
        if abs(angle) < 5:
            horizontal_lines.append(line[0])

# 确定液位高度(取水平直线y坐标的中位数)
if horizontal_lines:
    y_coords = [(y1 + y2) // 2 for x1, y1, x2, y2 in horizontal_lines]
    liquid_level_y = np.median(y_coords)
    print(f"液位高度对应的y坐标:{liquid_level_y}")
    # 可选:在图上画出液位线
    cv2.line(img, (0, int(liquid_level_y)), (img.shape[1], int(liquid_level_y)), (0,0,255), 2)
    cv2.imshow("Result", img)
    cv2.waitKey(0)

方法2:轮廓筛选(找水平长条轮廓)

通过轮廓检测筛选宽高比大的水平轮廓,对应液位线:

import cv2
import numpy as np

img = cv2.imread("test_tube.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5,5), 0)
thresh = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)

# 查找轮廓
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
liquid_contours = []

# 筛选宽高比>5、宽度>20的水平轮廓
for cnt in contours:
    x, y, w, h = cv2.boundingRect(cnt)
    if w / h > 5 and w > 20:
        liquid_contours.append((x, y, w, h))

# 确定液位高度(取符合条件轮廓的y坐标中间值)
if liquid_contours:
    # 按y坐标排序,优先取试管中部的轮廓
    liquid_contours.sort(key=lambda item: item[1])
    target_contour = liquid_contours[0]
    liquid_level_y = target_contour[1] + target_contour[3] // 2
    print(f"液位高度对应的y坐标:{liquid_level_y}")
    # 可选:画出轮廓和液位线
    cv2.rectangle(img, (target_contour[0], target_contour[1]), 
                  (target_contour[0]+target_contour[2], target_contour[1]+target_contour[3]), (0,255,0), 2)
    cv2.line(img, (0, int(liquid_level_y)), (img.shape[1], int(liquid_level_y)), (0,0,255), 2)
    cv2.imshow("Result", img)
    cv2.waitKey(0)

三、参数调整建议

如果检测效果不佳,可针对性调整以下参数:

  • 高斯模糊核大小:可尝试(3,3)或(7,7),适配不同模糊程度
  • 自适应阈值的blockSize:改为15、19等奇数,调整局部区域的计算范围
  • 霍夫直线检测的threshold、minLineLength:降低阈值或缩短最小线长,适配更短的液位线
  • 轮廓筛选的宽高比阈值:根据实际图片调整,比如改为3或7

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 16:14:59