这是我本科毕设的项目,想法来源于很火很成熟的车牌识别,数字式仪表识别与之类似,而且省去了识别汉字和字母的部分,使得系统识别准确性更高。但在定位时,由于不能利用颜色信息,定位的实现要稍作改变。
GitHub:
传送门
综合考虑系统需求,选用树莓派3B型作为控制器
树莓派性能强大、运行稳定、外形小巧,有丰富的接口引脚,自带Wi-Fi、摄像等模块。
摄像头选用树莓派官方摄像头,像素500万。
本系统使用python语言编程,利用opencv开源代码库,代码简单,调参容易
读入原图像:
img=cv2.imread('1.jpg')
blur = 3
img = cv2.GaussianBlur(img, (blur, blur), 0)
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, img_thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
在仪表图像的实际拍摄过程中,由于人手持的不稳定,采集到的图像很容易发生倾斜,若倾斜角度过大,会严重影响字符定位分割的效果,进而会对后续的识别产生不利影响,所以在倾斜严重时需要对图像进行旋转校正。本文使用Hough直线检测来矫正,由于Hough变换运算量过大,所以应先进行Canny边缘检测
Canny提取边缘:
edges = cv2.Canny(img_thresh,50,150,apertureSize = 7)
def hough_change(edges):
#霍夫变换
lines = cv2.HoughLines(edges,1,np.pi/180,0)
for rho,theta in lines[0]:
a = np.cos(theta)
b = np.sin(theta)
x0 = a*rho
y0 = b*rho
x1 = int(x0 + 1000*(-b))
y1 = int(y0 + 1000*(a))
x2 = int(x0 - 1000*(-b))
y2 = int(y0 - 1000*(a))
if x1 == x2 or y1 == y2:
rotate_img=img
else:
t = float(y2-y1)/(x2-x1)
rotate_angle = math.degrees(math.atan(t))
if rotate_angle > 45:
rotate_angle = -90 + rotate_angle
elif rotate_angle < -45:
rotate_angle = 90 + rotate_angle
rotate_img = ndimage.rotate(img, rotate_angle)
return rotate_img
对校正后的图进行闭开运算:
Matrix = np.ones((5, 3), np.uint8)
#闭开
img_edge1 = cv2.morphologyEx(img_thresh2, cv2.MORPH_CLOSE, Matrix)
Matrix = np.ones((5, 20), np.uint8)
img_edge2 = cv2.morphologyEx(img_edge1, cv2.MORPH_OPEN, Matrix)
然后再利用轮廓检测,检测矩形,再根据矩形的面积和长宽比初步确定表盘的位置。要注意的是,在此过程中,小数部分会被去除,暂时还没有想到较好的检测小数部分的方法。
粗分割后再利用投影法进行细分割并归一化:
本设计选用SVM(Support Vector Machine支持向量机)进行数字识别
SVM是一种分类器,其原理就是找到一个集合超平面将数据分离开,并使两类数据几何间隔最大。
对于线性不可分的数据集,则先进行非线性变换投射到高维空间再分割,这一过程由核函数完成。
使用python自带的tkinter可视化结构来实现用户界面的搭建和显示,由于时间关系以及设计需求,远程中心界面未进行设计。
用户界面和远程中心使用Socket进行通信:
完整代码:
完整代码下载
有任何问题欢迎联系,留言或者发邮箱[email protected]皆可