仪表识别中的数码识别算法
最近在做巡检机器人和仪表识别算法,巡检机器人拍摄的照片除了指针仪表和状态灯以外,还有一部分是数码计数的仪表,这样对仪表的数值的识别就需要后台代码具备检测文本和识别的功能了.
仪表面板
仪表面板
有关仪表识别的文章参考我以前的文章:
- 无人值守项目中传统仪表识别
- 实时仪表盘识别
- 有关自然场景下文本检测的文章见:自然场景下的文本检测和识别 EAST text detector and recognition
1. 数据准备
我们采用过OCR的方法和针对led数码的识别算法,做过测试.并买了一个数码计数器用于实际测试和数据采集,发现当前已有的OCR和算法不能很好的识别,原因在于:
- 实际应用中,照片和视频很难达到ocr的识别标准
- 光线和角度严重影响识别
- 数码很多情况下是能看到局部
所以,我们决定自己搭建模型,采集数据,训练出来一套可以实用的算法出来.
我们测试的数码计数器
我们采用摄像头,使用自然场景下文本检测的方法,采集分割生成数据集:
数据集目录 数据集目录 数据集分类2.搭建模型
考虑到图形比较简单,特征值也很明显,采用多层cnn模型就可以满足需求.
# CNN模型
model = Sequential()
# 卷积层和池化层
model.add(Conv2D(32, kernel_size=(3, 3), input_shape=(32,32,1), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(32, kernel_size=(3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))
# Dropout层
model.add(Dropout(0.25))
model.add(Conv2D(64, kernel_size=(3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(64, kernel_size=(3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))
model.add(Dropout(0.25))
model.add(Conv2D(128, kernel_size=(3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(128, kernel_size=(3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))
model.add(Dropout(0.25))
model.add(Flatten())
# 全连接层
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(128, activation='relu'))
model.add(Dense(n_classes, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
这个模型非常简单,是一个标准的cnn模型.对于简单的数字识别已经足够了.
3.训练模型
我们采集了足够多的图片,按照分类从0-9,放入数据集中.
数据集生成
def generate(batch, size):
"""Data generation and augmentation
# Arguments
batch: Integer, batch size.
size: Integer, image size.
# Returns
train_generator: train set generator
validation_generator: validation set generator
count1: Integer, number of train set.
count2: Integer, number of test set.
"""
# Using the data Augmentation in traning data
ptrain = 'data/train'
pval = 'data/test'
datagen1 = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
rotation_range=30,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True)
datagen2 = ImageDataGenerator(rescale=1. / 255)
train_generator = datagen1.flow_from_directory(
ptrain,
target_size=(size, size),
batch_size=batch,
class_mode='categorical',
color_mode='grayscale')
validation_generator = datagen2.flow_from_directory(
pval,
target_size=(size, size),
batch_size=batch,
class_mode='categorical',
color_mode='grayscale')
count1 = 0
for root, dirs, files in os.walk(ptrain):
for each in files:
count1 += 1
count2 = 0
for root, dirs, files in os.walk(pval):
for each in files:
count2 += 1
return train_generator, validation_generator, count1, count2
开始训练,训练完成保存数据集:
train_generator, validation_generator, count1, count2 = generate(batch, size)
n_classes = num_classes
input_shape = (size, size, 1)
hist = model.fit_generator(
train_generator,
validation_data=validation_generator,
steps_per_epoch=count1 // batch,
validation_steps=count2 // batch,
epochs=epochs
)
model.save_weights('model/digital201908.h5')
4.测试检验
采用摄像头,使用opencv采集摄像头数据,采用自然场景下文本检测算法检测数字部分,并做分割处理,把处理的图片送到 刚才训练好的模型中做推理,
并把识别结果写到图片上.
测试检验
网友评论