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

如何用OpenCV检测仪表图像中的全部水平线并获取其坐标

解决OpenCV仪表图像水平线检测不全的问题

仪表图像

问题分析

你的代码中水平结构元素尺寸固定为(40,1),只能匹配长度≥40的水平线,仪表里的短刻度线会被漏掉。另外cv.findContours的返回值处理不严谨,不同OpenCV版本返回值数量不同,直接遍历会导致报错。

改进后的代码

import cv2 as cv
import numpy as np

# 读取图像(替换为你的图像加载逻辑)
# image = cv.imread("meter_image.png")
result = image.copy()

print("[INFO] Converting to Gray...\n")
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
print("[INFO] Converted to Gray.\n")

print("[INFO] Applying Thresholding...\n")
thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
print("[INFO] Threshold Applied.\n")

# 生成多尺寸水平结构元素,覆盖不同长度的水平线
horizontal_kernels = [
    cv.getStructuringElement(cv.MORPH_RECT, (15, 1)),
    cv.getStructuringElement(cv.MORPH_RECT, (40, 1)),
    cv.getStructuringElement(cv.MORPH_RECT, (60, 1))
]

# 合并不同核的检测结果
detect_horizontal = np.zeros_like(thresh)
for kernel in horizontal_kernels:
    temp = cv.morphologyEx(thresh, cv.MORPH_OPEN, kernel, iterations=1)
    detect_horizontal = cv.bitwise_or(detect_horizontal, temp)

# 适配不同OpenCV版本的轮廓返回值
cnts = cv.findContours(detect_horizontal, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

print("所有水平线坐标信息:")
for c in cnts:
    # 通过边界框获取水平线的起止坐标与中心坐标
    x, y, w, h = cv.boundingRect(c)
    start_point = (x, y)
    end_point = (x + w, y)
    center_point = (x + w // 2, y)
    print(f"起止点:{start_point} -> {end_point},中心坐标:{center_point}")
    cv.drawContours(result, [c], -1, (36,255,12), 2)

cv.imshow('result', result)
cv.waitKey(0)
cv.destroyAllWindows()

关键改进点

  • 多尺寸结构元素:使用15、40、60三种宽度的水平核,覆盖仪表中长短不一的水平线,通过位运算合并检测结果,避免遗漏短刻度线。
  • 适配轮廓返回值:处理不同OpenCV版本findContours的返回格式,避免报错。
  • 完整坐标输出:通过boundingRect提取每条水平线的起止坐标和中心坐标,满足你对x、y信息的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 02:20:49