项目简介

利用 OpenCV 和笔记本 PC 的摄像头(或者外接摄像头)识别万用表电流值。

步骤:

1、定位屏幕

照片要光线均匀,无大面积阴影。
另外,这款万用表轮廓不明显,故贴纸使轮廓更分明。

首先对图像做:灰度化、高斯滤波、边缘识别。
在处理后的图片上识别轮廓,并提取最大轮廓,即为屏幕区域。
得到:

2、提取屏幕,并做一系列图像处理,得到黑白屏幕

透视变换,提取屏幕区域:

图片二值化、形态学变换(腐蚀、膨胀):

3、提取数字,并分割

提取图片数字区域,消除边缘阴影,然后使用垂直投影法分割数字。

4、识别数字

进一步提取单个数字中每一根数码管的大致区域,通过统计该区域白色像素占比,若占比超过40%(有误差),则认为该管为亮。然后查表,判断数字。


结果:

代码附上:

# import the necessary packages
from imutils.perspective import four_point_transform
from imutils import contours
import imutils
import cv2
import numpy as np
from openpyxl import Workbook
from openpyxl import load_workbook
from openpyxl.writer.excel import ExcelWriter# define the dictionary of digit segments so we can identify
# each digit on the thermostat
DIGITS_LOOKUP = {(1, 1, 1, 0, 1, 1, 1): 0,(0, 0, 1, 0, 0, 1, 0): 1,(1, 0, 1, 1, 1, 0, 1): 2,(1, 0, 1, 1, 0, 1, 1): 3,(0, 1, 1, 1, 0, 1, 0): 4,(1, 1, 0, 1, 0, 1, 1): 5,(1, 1, 0, 1, 1, 1, 1): 6,(1, 1, 1, 0, 0, 1, 0): 7,(1, 1, 1, 1, 1, 1, 1): 8,(1, 1, 1, 1, 0, 1, 1): 9
}def get_vvList(list_data):#取出list中像素存在的区间vv_list=list()v_list=list()for index,i in enumerate(list_data):if i>0:v_list.append(index)else:if v_list:vv_list.append(v_list)#list的clear与[]有区别v_list=[]return vv_list# load the example image
image = cv2.imread("15.jpg")
# pre-process the image by resizing it, converting it to
# graycale, blurring it, and computing an edge map
image = imutils.resize(image, height=500)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(blurred, 128, 200)# find contours in the edge map, then sort them by their
# size in descending order
cnts,hi = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# the largest contour(default: target) is in the first place after sorting
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
cv2.drawContours(image,cnts,0,(0,0,255),3)
displayCnt = None
# loop over the contours
for c in cnts:# approximate the contourperi = cv2.arcLength(c, True)approx = cv2.approxPolyDP(c, 0.02 * peri, True)# if the contour has four vertices, then we have found# the thermostat displayif len(approx) == 4:displayCnt = approxbreak
# extract the thermostat display, apply a perspective transform to it
warped = four_point_transform(gray, displayCnt.reshape(4, 2))
output = four_point_transform(image, displayCnt.reshape(4, 2))#
thresh = cv2.threshold(warped, 0, 255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]# kernel = np.ones((5,5),np.uint8)
# erosion = cv2.erode(thresh,kernel)
# dst = cv2.dilate(erosion,kernel)
# dst1 = cv2.dilate(dst,kernel)kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1, 5))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel,2)ROI = thresh.copy()[20:103, 20:168]
# 黑白反转
where_0 = np.where(ROI == 0)
where_255 = np.where(ROI == 255)
ROI[where_0] = 255
ROI[where_255] = 0
print(thresh.shape)rows, cols = ROI.shape
ver_list = [0]*cols
for j in range(cols):for i in range(rows):if ROI.item(i,j)==0:ver_list[j]=ver_list[j]+1
'''
对ver_list中的元素进行筛选,可以去除一些噪点qq
'''
ver_arr=np.array(ver_list)
ver_arr[np.where(ver_arr<1)]=0
ver_list=ver_arr.tolist()#绘制垂直投影
img_white=np.ones(shape=(rows,cols),dtype=np.uint8)*255
for j in range(cols):pt1=(j,rows-1)pt2=(j,rows-1-ver_list[j])cv2.line(img_white,pt1,pt2,(0,),1)
cv2.imshow('垂直投影',img_white)digits = []#切割单一字符
vv_list=get_vvList(ver_list)
for i in vv_list:img_ver=ROI.copy()[:,i[0]:i[-1]]where_0 = np.where(img_ver == 0)where_255 = np.where(img_ver == 255)img_ver[where_0] = 255img_ver[where_255] = 0(roiH, roiW) = img_ver.shape(dW, dH) = (int(roiW * 0.3), int(roiH * 0.1))dHC = int(roiH * 0.05)# define the set of 7 segmentssegments = [((0, 0), (roiW, dH)),  # top((0, 0), (dW, roiH // 2)),  # top-left((roiW - dW, 0), (roiW, roiH // 2)),  # top-right((0, (roiH // 2) - dHC), (roiW, (roiH // 2) + dHC)),  # center((0, roiH // 2), (dW, roiH)),  # bottom-left((roiW - dW, roiH // 2), (roiW, roiH)),  # bottom-right((0, roiH - dH), (roiW, roiH))  # bottom]on = [0] * len(segments)# loop over the segmentsfor (i, ((xA, yA), (xB, yB))) in enumerate(segments):# extract the segment ROI, count the total number of# thresholded pixels in the segment, and then compute# the area of the segmentsegROI = img_ver[yA:yB, xA:xB]total = cv2.countNonZero(segROI)area = (xB - xA) * (yB - yA)# if the total number of non-zero pixels is greater than# 50% of the area, mark the segment as "on"proportion = total / float(area)print(proportion)if proportion > 0.35:on[i] = 1# lookup the digit and draw it on the image# special: digit = 1if roiH > 5 * roiW:digit = 1else:digit = DIGITS_LOOKUP[tuple(on)]print(digit)digits.append(digit)cv2.imshow('单一字符', img_ver)cv2.waitKey(0)cv2.putText(warped, str(digits), (15, 15),cv2.FONT_HERSHEY_SIMPLEX, 0.65, (255, 255, 0), 2)
print(digits)cv2.imshow("Output1", image)
cv2.imshow("Output2", warped)
cv2.imshow("Output3", thresh)cv2.waitKey(0)

还有一份带简单UI界面,摄像头实时识别版,且有绘图功能,如需要联系我:

参考:
使用 OpenCV 和 Python 识别数字
文本分割之垂直投影法基于OpenCV(python)的实现

OpenCV-Python 识别万用表七段数码管电流值相关推荐

  1. Python之绘制七段数码管

    今天课上老师教我们如何运用Python来绘制七段数码管,首先我们要了解七段数码管是怎么组成的,如下图 我们知道七段数码是怎么组成后,就开始来绘制七段数码管了.  一,绘制单个数码管 代码如下: imp ...

  2. 数字图像处理 使用opencv+python识别七段数码显示器的数字

    一.什么是七段数码显示器 七段LCD数码显示器有很多叫法:段码液晶屏.段式液晶屏.黑白笔段屏.段码LCD液晶屏.段式显示器.TN液晶屏.段码液晶显示器.段码屏幕.笔段式液晶屏.段码液晶显示屏.段式LC ...

  3. opencv python 识别视频水印_opencv+python实现视频实时质心读取

    利用opencv+python实现以下功能: 1)获取实时视频,分解帧频: 2)将视频做二值化处理: 3) 将视频做滤波处理(去除噪点,获取准确轮廓个数): 4)识别图像轮廓: 5)计算质心: 6)描 ...

  4. Python实例:七段数码管

    实例:七段数码管 代码如下(示例): import turtle def drawLine(draw): #绘制单段数码管turtle.pendown() if draw else turtle.pe ...

  5. python turtle 绘制七段数码管以及14段数码管显示字母和时间

    目录 书上的7段数码管,显示时间 书上的7断数码管显示应功都看过了,这里顺便提供一下` 看看显示原理 14段模型 14位数码管,画英文,和数字 书上的7段数码管,显示时间 书上的7断数码管显示应功都看 ...

  6. 用Python制作时间七段数码管

    import turtle#导入库 import time def drawGap(): #定义函数,绘制数码管之间的间隙turtle.penup()turtle.fd(5) def drawLine ...

  7. 使用opencv+python识别七段数码显示器的数字识别

    # 导入必要的包 from imutils.perspective import four_point_transform from imutils import contours import im ...

  8. OpenCV+Python识别车牌和字符分割

    本篇文章主要基于python语言和OpenCV库(cv2)进行车牌区域识别和字符分割,开篇之前针对在python中安装opencv的环境这里不做介绍,可以自行安装配置! 车牌号检测需要大致分为四个部分 ...

  9. opencv+python识别猪

    背景:在车载监控回传的视频里判断该车里是否有猪 解决思路:在回传视频里做物体识别,如果有猪就框出来并且给出一个代表值 day1 2021-10-27 设想:物体识别,并且在图中框出来猪 1.找正样本 ...

  10. python turtle绘制七段数码管日期时间(注释)

    import turtle,time # 绘制单段数码管 #每次画笔描绘 真假 长度 描绘完成之后向右旋转角度 def drawGap():#每段描绘空格5像素turtle.penup()turtle ...

最新文章

  1. F5内网大二层负载均衡业务访问故障解析(CISCO OTV+LISP-MTU问题导致)
  2. Struts 声明式异常处理和个性化异常处理(转)
  3. 1.5 Map集合:HashMap 和TreeMap 类
  4. 大粤桂谋定发展-丰收节交易会·林裕豪:从玉农业协作项目
  5. Go 语言web 框架 Gin 练习6
  6. MUI 支付宝支付接入
  7. 【敏感度,查询,裁剪代码实现】差分隐私代码实现系列(六)
  8. 小女出世,暂停工作,全职照料大人小孩
  9. 开始学习 refactoring:improving the design of existing code
  10. HTML连接共享文件,怎么连接共享文件夹
  11. TensorFlow saved_model 模块
  12. jQuery - 滚动条插件 NiceScroll 使用详解(滚动条美化)
  13. 125、什么是核心交换机的链路聚合、冗余、堆叠、热备份
  14. 【微信小程序】解决Echarts在微信小程序tab切换时的显示问题
  15. 史上最全的工业相机CCD/CMOS靶面尺寸规格说明
  16. 云大使的返利规则是什么
  17. Eclipse照亮Java众生 扩大地盘
  18. linux 软件包kbd 位置,1.10.42 6.42. Kbd-1.12 - Linux 系统构建指南
  19. 【转帖】时间管理(GTD)的黑洞
  20. 小白买基金做好三件事

热门文章

  1. linux服务器校对时间方法
  2. Everyone Piano键盘钢琴软件
  3. PMP备考|通关宝典
  4. 第七届蓝桥杯c语言a组答案,第七届蓝桥杯 C语言A组试题.pdf
  5. vs2013制作滚屏软件
  6. Smart3D运行过程中遇到的问题(持续更新)
  7. 地图转换|用arcgis 将cad转kmz
  8. mysql数据怎么提取出来分析_Mysql数据提取器
  9. 呼吸流水灯c语言程序,单片机流水灯与呼吸灯结合-滴水灯程序及详细教程
  10. 加壳后软件报毒解决办法