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

如何使用Python与OpenCV实现模拟指针仪表盘读数识别

Python+OpenCV模拟指针仪表盘读数实现方案

原始素材

  • 待识别原始仪表盘图像:
    原始待识别仪表盘
  • 现有预处理后效果:
    预处理后效果

现有代码基础

当前已经实现图像缩放、HSV空间转换、掩码提取、霍夫圆检测表盘区域、初步轮廓绘制功能,核心代码如下:

import os
import glob
import cv2
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
img = cv2.imread('/home/administrator/Downloads/read_analogue_gauge_v1_1/images/gaugemio.jpg')
def rescaleFrame(frame, scale=0.5):
        width = int(frame.shape[1]*scale)
        height = int(frame.shape[0]*scale)
        dimensions = (width, height)
        return cv2.resize(frame, dimensions, interpolation=cv2.INTER_AREA)
resized_image = rescaleFrame(img)
img = resized_image
img_hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
img_hsv = cv2.bitwise_not(img_hsv)
lower_black, upper_black = np.array([0, 0, 0]), np.array([180, 255, 65])
mask = cv2.inRange(img_hsv, lower_black, upper_black)

blank = np.zeros((747, 714), dtype='uint8')
blank2 = np.zeros((747, 714), dtype='uint8')
blurred = cv2.blur(~mask, (9, 9))

circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT,1, 400, param1=50, param2=100, minRadius=200, maxRadius=0)
detected_circles = np.uint16(np.around(circles))
dimension = img.shape

for(x, y, r) in detected_circles[0, :]:
    circle = cv2.circle(blank, (x,y),r, 255, -1 )
    cv2.circle(img, (x,y),r, (0,255,0),3)
    cv2.circle(img, (x,y),2, (0,0,255),3)
    cv2.circle(img, (x,y),30, (0,0,255),3)
    circ_col = x
    circ_row = y
bitwise_and = cv2.bitwise_and(blank, mask)
canny2 = cv2.Canny(bitwise_and, 50, 150, apertureSize=3)
blurred2 = cv2.blur(bitwise_and, (15, 15))
contours, hierarchy = cv2.findContours(blurred2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img, contours, -1, (0, 255, 0), 2)
cv2.imshow('hi',resized_image)

cv2.waitKey(0)

后续实现技巧

指针精准定位

  • 先做ROI提纯:拿到表盘圆心坐标、半径后,直接将圆形区域外所有像素置0,再进一步保留半径0.1r~0.9r的环形区域,过滤掉圆心转轴、外圈刻度边框的干扰,指针只会出现在这个环形范围内。
  • 用概率霍夫直线检测替代普通轮廓查找:在提纯后的二值掩码上调用cv2.HoughLinesP,参数设置minLineLength为0.3r、maxLineGap为5,低阈值多检线段,后续做规则过滤即可。
  • 线段过滤规则:直接丢弃所有到圆心距离大于10像素的线段,剩余线段中取长度最长的即为指针——指针是表盘内唯一过圆心、长度远大于刻度线的深色直线结构,这个规则误判率极低。如果指针是红、白等特殊颜色,可以单独提取对应颜色的HSV掩码做检测,精度比提取黑色更高。
  • 指针端点修正:找到指针线段后,丢弃离圆心近的端点,统一用检测到的表盘圆心作为指针固定端,离圆心远的端点作为指针尖端,避免转轴处反光、磨损带来的定位偏差。

角度与读数换算

  • 提前做参考点标定:不需要硬套角度公式,先标定两个基准点即可:记录0刻度对应的指针尖端坐标、满量程刻度对应的指针尖端坐标,用math.atan2(y - circ_row, x - circ_col)分别计算两个基准点、当前指针尖端相对于圆心的角度,注意将计算结果统一映射到0~360度范围,适配OpenCV左上角为原点、y轴向下的坐标规则。
  • 线性映射读数:计算当前指针角度在0刻度角度、满量程角度之间的占比,直接按比例映射到量程区间即可。例如0刻度对应150度、读数0,满量程对应30度、读数1.6MPa,当前指针角度90度时,读数为(150-90)/(150-30)*1.6 = 0.8MPa。
  • 非线性刻度适配:如果是欧姆表这类非线性刻度的表盘,多标定3~5个中间刻度点的角度值,用分段线性插值计算读数即可,不需要拟合复杂曲线,精度足够工业场景使用。

效果优化建议

  • 预处理优化:去掉固定HSV阈值提黑色的逻辑,先对原图灰度图做CLAHE自适应直方图均衡提升对比度,再用自适应阈值做二值化,对光线变化、反光场景的鲁棒性会高很多。
  • 去掉硬编码参数:当前代码里把blank画布尺寸写死为747*714、霍夫圆半径范围写死为200以上,换图很容易报错,改成动态参数:画布尺寸和输入图保持一致,霍夫圆最小/最大半径按输入图短边的0.3倍、0.48倍设置,兼容性更好。
  • 增加误检校验:增加读数合理性判断,如果计算出的指针角度超出0刻度到满量程的范围,或者连续帧读数跳变超过满量程的20%,直接判定为误检,用上一次的有效读数兜底,适合实时视频流读数场景。
  • 倾斜适配:如果拍摄角度存在倾斜,检测到表盘圆后用cv2.warpPolar做极坐标展开,把圆形表盘拉成平矩形再定位指针,可以完全消除透视倾斜带来的角度计算误差。
  • 调试逻辑修正:当前代码最后cv2.imshow显示的是未做任何绘制的原始缩放图,改成显示处理后的img变量,才能实时看到圆检测、轮廓、指针的绘制效果,方便调参。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 23:33:19