§01 七段数码
1.1 数据库来源
这个数据库的主要的图片都来自于网络上相关的LED,LCD七段数码管的图片。不同视角、不同颜色、不同分辨率。总数是189个图片。
1.1.1 数据命名
每个图片的命名格式为:
其中:NNN:图片的序列号,从001 开始递增;MMMM是图片内数字的内容。如果为N表示改位的数字不是0 ~ 9的内容。图片可能是BMP或者JPEG的格式。
▲ 图1.1.1 图片命名格式
1.1.2 图片数据下载
图片数据库集合可以从一下两个链接进行下载。
- AI Studio:中等规模的区段数码管数据集合
- CSDN: 7Seg.zip:这是一个中等规模的七段数码管的数据集合
1.2 数据库预处理
1.2.1 将数据库图片进行分割
(1)图片库分割
将所有的图片中的数码进行分割,转换成灰度图,并归一化成48×48的图片。
-
转换完之后的数据库:
-
数量
:853
尺寸
:48×48
颜色
:灰度图片
from headm import * # =
import cv2
from tqdm import tqdm
picdir = '/home/aistudio/work/7seg/7Seg'
filedim = [s for s in os.listdir(picdir) if s.upper().find('BMP') > 0 or s.upper().find('JPG') > 0]
filedim = sorted(filedim)
outdir = '/home/aistudio/work/7seg/pic48'
totalpic = 0
OUT_SIZE = 48
for f in tqdm(filedim):
fn = os.path.join(picdir, f)
img = cv2.imread(fn)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
imgwidth = gray.shape[1]
imgheight = gray.shape[0]
numstr = f.split('.')[0].split('-')[1]
numnum = len(numstr)
for i in range(numnum):
left = imgwidth * i // numnum
right = imgwidth * (i + 1) // numnum
data = gray[0:imgheight, left:right]
dataout = cv2.resize(data, (OUT_SIZE, OUT_SIZE))
outfn = os.path.join(outdir, '%04d_%s.BMP'%(totalpic, numstr[i]))
totalpic += 1
cv2.imwrite(outfn, dataout)
printt(totalpic:)
▲ 图1.2.1 所有图片图片分割转换成灰度图片
1.2.2 转换成训练数据集合
将生成的图片库转换成训练数据集和,主要进行三部分处理:
- 将灰度进行反色处理,形成扩增一倍的数据;
- 将所有数据进行归一化:均值为0.5, 方差为1;
▲ 图1.2.2 正反两种颜色,归一化之后的图像
from headm import * # =
import paddle
import paddle.fluid as fluid
import paddle.nn.functional as F
from paddle import to_tensor as TT
import cv2
outdir = '/home/aistudio/work/7seg/pic48'
filedim = sorted([s for s in os.listdir(outdir) if s.find('BMP') > 0])
picarray = []
labeldim = []
for f in filedim:
fn = os.path.join(outdir, f)
img = cv2.imread(fn)
gray = img[:,:,0]
gray = gray - mean(gray)
stdd = std(gray)
gray1 = gray / stdd
gray2 = gray * (-1.0)
ff = f.split('.')[0].split('_')[-1]
if ff.isdigit():
ff = int(ff)
picarray.append(gray1)
picarray.append(gray2)
labeldim.append(ff)
labeldim.append(ff)
printt(shape(picarray))
printt(labeldim)
outfile = '/home/aistudio/work/7seg/seg7_48.npz'
savez(outfile, pic=picarray, label=labeldim)
(1)显示数据库中的数字
from headm import * # =
import cv2
outfile = '/home/aistudio/work/7seg/seg7_48.npz'
data = load(outfile)
printt(data.files:)
picimage = data['pic']
label = data['label']
printt(shape(picimage):, label:)
row_num = 6
col_num = 10
plt.clf()
plt.figure(figsize=(12,8))
for i in range(row_num):
for j in range(col_num):
id = i*col_num + j
plt.subplot(row_num, col_num, id+1)
plt.axis('off')
plt.imshow(picimage[id])
▲ 图1.2.3 形成的数据库字符
§02 训练网络
2.1 构建LeNet
2.1.1 网络代码
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST1.PY -- by Dr. ZhuoQing 2022-01-03
#
# Note:
#============================================================
from headm import * # =
import paddle
import paddle.fluid as fluid
from paddle import to_tensor as TT
from paddle.nn.functional import square_error_cost as SQRC
datafile = '/home/aistudio/work/7seg/seg7_48.npz'
data = load(datafile)
lcd = data['pic']
llabel = data['label']
printt(lcd.shape, llabel.shape)
#------------------------------------------------------------
dl = [(d,l) for d,l in zip(lcd, llabel)]
random.shuffle(dl)
printt(shape(dl))
train_ratio = 0.8
train_num = int(len(llabel) * train_ratio)
train_lcd = [a[0] for a in dl[:train_num]]
train_label = [a[1] for a in dl[:train_num]]
test_lcd = array([a[0] for a in dl[train_num:]])
test_label = array([a[1] for a in dl[train_num:]])
#------------------------------------------------------------
class Dataset(paddle.io.Dataset):
def __init__(self, num_samples):
super(Dataset, self).__init__()
self.num_samples = num_samples
def __getitem__(self, index):
data = train_lcd[index][newaxis,:,:]
label = train_label[index]
return paddle.to_tensor(data,dtype='float32'), paddle.to_tensor(label,dtype='int64')
def __len__(self):
return self.num_samples
_dataset = Dataset(len(train_label))
train_loader = paddle.io.DataLoader(_dataset, batch_size=200, shuffle=True)
#------------------------------------------------------------
test_d = paddle.to_tensor([a[newaxis,:,:] for a in test_lcd], dtype='float32')
test_l = paddle.to_tensor(test_label[:, newaxis], dtype='int64')
printt(shape(test_d):, shape(test_l):)
#------------------------------------------------------------
imgwidth = 48
imgheight = 48
inputchannel = 1
kernelsize = 5
targetsize = 10
ftwidth = ((imgwidth-kernelsize+1)//2-kernelsize+1)//2
ftheight = ((imgheight-kernelsize+1)//2-kernelsize+1)//2
class lenet(paddle.nn.Layer):
def __init__(self, ):
super(lenet, self).__init__()
self.conv1 = paddle.nn.Conv2D(in_channels=inputchannel, out_channels=6, kernel_size=kernelsize, stride=1, padding=0)
self.conv2 = paddle.nn.Conv2D(in_channels=6, out_channels=16, kernel_size=kernelsize, stride=1, padding=0)
self.mp1 = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
self.mp2 = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
self.L1 = paddle.nn.Linear(in_features=ftwidth*ftheight*16, out_features=120)
self.L2 = paddle.nn.Linear(in_features=120, out_features=86)
self.L3 = paddle.nn.Linear(in_features=86, out_features=targetsize)
def forward(self, x):
x = self.conv1(x)
x = paddle.nn.functional.relu(x)
x = self.mp1(x)
x = self.conv2(x)
x = paddle.nn.functional.relu(x)
x = self.mp2(x)
x = paddle.flatten(x, start_axis=1, stop_axis=-1)
x = self.L1(x)
x = paddle.nn.functional.relu(x)
# x = paddle.fluid.layers.dropout(x, 0.2)
x = self.L2(x)
x = paddle.nn.functional.relu(x)
x = self.L3(x)
return x
model = lenet()
#------------------------------------------------------------
optimizer = paddle.optimizer.Adam(learning_rate=0.001, parameters=model.parameters())
def train(model):
model.train()
epochs = 200
for epoch in range(epochs):
for batch, data in enumerate(train_loader()):
out = model(data[0])
loss = paddle.nn.functional.cross_entropy(out, data[1])
acc = paddle.metric.accuracy(out, data[1]).numpy()
preout = model(test_d)
test_acc = paddle.metric.accuracy(preout, test_l).numpy()
loss.backward()
optimizer.step()
optimizer.clear_grad()
printt('Epoch:{}, Accuracys:{}, Test:{}'.format(epoch, acc, test_acc))
train(model)
paddle.save(model.state_dict(), './work/seg7model.pdparams')
#------------------------------------------------------------
filename = '/home/aistudio/stdout.txt'
accdim = []
testdim = []
with open(filename, 'r') as f:
for l in f.readlines():
ll = l.split(':[')
if len(ll) < 3: continue
lacc = ll[-2].split(']')
if len(lacc) < 2: continue
accdim.append(float(lacc[0]))
tacc = ll[-1].split(']')
if len(tacc) < 2: continue
testdim.append(float(tacc[0]))
plt.figure(figsize=(12, 8))
plt.plot(accdim, label='Train ACC')
plt.plot(testdim, label='Test ACC')
plt.xlabel("Step")
plt.ylabel("Acc")
plt.grid(True)
plt.tight_layout()
plt.show()
#------------------------------------------------------------
# END OF FILE : TEST1.PY
#============================================================
2.1.2 训练结果
▲ 图2.1.1 训练精度和测试精度
2.1.3 错误的样本
from headm import * # =
import paddle
import paddle.fluid as fluid
import paddle
import paddle.fluid as fluid
from paddle import to_tensor as TT
from paddle.nn.functional import square_error_cost as SQRC
datafile = '/home/aistudio/work/7seg/seg7_48.npz'
data = load(datafile)
lcd = data['pic']
llabel = data['label']
printt(lcd.shape, llabel.shape)
test_d = paddle.to_tensor([a[newaxis,:,:] for a in lcd], dtype='float32')
test_l = paddle.to_tensor(llabel[:, newaxis], dtype='int64')
printt(shape(test_d):, shape(test_l):)
imgwidth = 48
imgheight = 48
inputchannel = 1
kernelsize = 5
targetsize = 10
ftwidth = ((imgwidth-kernelsize+1)//2-kernelsize+1)//2
ftheight = ((imgheight-kernelsize+1)//2-kernelsize+1)//2
class lenet(paddle.nn.Layer):
def __init__(self, ):
super(lenet, self).__init__()
self.conv1 = paddle.nn.Conv2D(in_channels=inputchannel, out_channels=6, kernel_size=kernelsize, stride=1, padding=0)
self.conv2 = paddle.nn.Conv2D(in_channels=6, out_channels=16, kernel_size=kernelsize, stride=1, padding=0)
self.mp1 = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
self.mp2 = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
self.L1 = paddle.nn.Linear(in_features=ftwidth*ftheight*16, out_features=120)
self.L2 = paddle.nn.Linear(in_features=120, out_features=86)
self.L3 = paddle.nn.Linear(in_features=86, out_features=targetsize)
def forward(self, x):
x = self.conv1(x)
x = paddle.nn.functional.relu(x)
x = self.mp1(x)
x = self.conv2(x)
x = paddle.nn.functional.relu(x)
x = self.mp2(x)
x = paddle.flatten(x, start_axis=1, stop_axis=-1)
x = self.L1(x)
x = paddle.nn.functional.relu(x)
x = self.L2(x)
x = paddle.nn.functional.relu(x)
x = self.L3(x)
return x
model = lenet()
model.set_state_dict(paddle.load('./work/seg7model1.pdparams'))
preout = model(test_d)
preid = paddle.argmax(preout, axis=1).numpy()
test_acc = paddle.metric.accuracy(preout, test_l).numpy()
printt(test_acc)
printt(preid)
errid = where(llabel != preid)
printt(errid)
printt(len(errid[0]))
row_num = 4
col_num = 8
plt.figure(figsize=(12,8))
for i in range(row_num):
for j in range(col_num):
id = i*col_num+j
err = errid[0][id]
title = '%d->%d'%(llabel[err], preid[err])
plt.subplot(row_num, col_num, id+1)
plt.axis('off')
plt.title(title)
plt.imshow(lcd[err])
▲ 图2.1.2 模型识别错误的样本
2.2 扩展样本
将原来的样本进行扩充。方法:
- 每一个样本高度、宽度放大1/0.85倍,总共形成原来样本四倍。
然后进行重新训练,错误识别率就大幅度下降了。
▲ 图3.1 模型识别错误的样本
§03 应用网络
3.1 检查原有图片
检查原有图片,有以下两个图片识别存在错误:
▲ 图3.1.1 识别为:1233
▲ 图3.1.2 识别为20143910
from headm import * # =
import paddle
import paddle.fluid as fluid
import cv2
imgwidth = 48
imgheight = 48
inputchannel = 1
kernelsize = 5
targetsize = 10
ftwidth = ((imgwidth-kernelsize+1)//2-kernelsize+1)//2
ftheight = ((imgheight-kernelsize+1)//2-kernelsize+1)//2
class lenet(paddle.nn.Layer):
def __init__(self, ):
super(lenet, self).__init__()
self.conv1 = paddle.nn.Conv2D(in_channels=inputchannel, out_channels=6, kernel_size=kernelsize, stride=1, padding=0)
self.conv2 = paddle.nn.Conv2D(in_channels=6, out_channels=16, kernel_size=kernelsize, stride=1, padding=0)
self.mp1 = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
self.mp2 = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
self.L1 = paddle.nn.Linear(in_features=ftwidth*ftheight*16, out_features=120)
self.L2 = paddle.nn.Linear(in_features=120, out_features=86)
self.L3 = paddle.nn.Linear(in_features=86, out_features=targetsize)
def forward(self, x):
x = self.conv1(x)
x = paddle.nn.functional.relu(x)
x = self.mp1(x)
x = self.conv2(x)
x = paddle.nn.functional.relu(x)
x = self.mp2(x)
x = paddle.flatten(x, start_axis=1, stop_axis=-1)
x = self.L1(x)
x = paddle.nn.functional.relu(x)
x = self.L2(x)
x = paddle.nn.functional.relu(x)
x = self.L3(x)
return x
model = lenet()
model.set_state_dict(paddle.load('./work/seg7model4.pdparams'))
OUT_SIZE = 48
def pic2netinput(imgfile):
img = cv2.imread(imgfile)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
imgwidth = gray.shape[1]
imgheight = gray.shape[0]
f = os.path.basename(imgfile)
numstr = f.split('.')[0].split('-')[1]
numnum = len(numstr)
imgarray = []
labeldim = []
for i in range(numnum):
left = imgwidth * i // numnum
right = imgwidth * (i + 1) // numnum
data = gray[0:imgheight, left:right]
dataout = cv2.resize(data, (OUT_SIZE, OUT_SIZE))
dataout = dataout - mean(dataout)
stdd = std(dataout)
dataout = dataout / stdd
if numstr[i].isdigit():
imgarray.append(dataout[newaxis,:,:])
labeldim.append(int(numstr[i]))
test_i = paddle.to_tensor(imgarray, dtype='float32')
test_label = array(labeldim)
test_l = paddle.to_tensor(test_label[:, newaxis], dtype='int64')
return test_i, test_l
picdir = '/home/aistudio/work/7seg/7Seg'
filedim = [s for s in os.listdir(picdir) if s.upper().find('BMP') > 0 or s.upper().find('JPG') > 0]
filedim = sorted(filedim)
def checkimglabel(imgfile):
inp, label = pic2netinput(imgfile)
preout = model(inp)
preid = paddle.argmax(preout, axis=1).numpy().flatten()
label = label.numpy().flatten()
error = where(label != preid)[0]
return error, preid
for f in filedim:
imgfile = os.path.join(picdir, f)
error,id = checkimglabel(imgfile)
if len(error) > 0:
printt(error, f, id)
img = cv2.imread(imgfile)
plt.clf()
plt.figure(figsize=(8,8))
plt.axis("off")
plt.imshow(img)
plt.show()
3.2 检查新的LCD数字
3.2.1 准备测试数据集合
在网络上搜集到一些LCD数字进行测试。总共35张LCD。
▲ 图3.2.1 重新搜集LCD数字
3.2.2 测试数字识别
利用模型识别,存在以下两个图片识别存在错误:
▲ 图3.2.2 识别成1234557890
▲ 图3.2.3 识别成1335
以上两个图片识别错误应该与截取数字错误有关系。
3.3 测试新的LED数字
搜集了62张LED数字图片。
▲ 图3.2.4 测试LED图片
3.3.1 出现的错误样本
出现的错误主要集中在蓝色LED,他们在灰度空间无法显示出亮度的差别。
▲ 图3.3.2 识别成8881
▲ 图3.3.3 识别成01888038
▲ 图3.3.4 识别成8888
▲ 图3.3.5 识别成8888
以上图片可以看到主要的错误集中在蓝色LED,这与它们在灰度图上无法显示出亮度差别。解决这个问题需要通过颜色空间来进行。
下面这个数字识别成2001,还是与最后一个数字对应的位置错误有关系。
▲ 图3.3.6 识别成2001
※ 测试总结 ※
利用CNN对于七段数码进行识别,包括LCD,LED不同分辨率的情况进行测试。由于是将原有的数字转换成48×48灰度数字图片,所以对于对比度不高的图片会造成识别错误。另外,由于这些数字相距比较近,所以图片分割如果出现错误,也会直接导致识别的错误。
4.1 改进的方向
为了进一步提高数码识别的精度,可以:
- 增加更多的训练样本;
- 转换到彩色空间;
- 增加自动定位分割的算法来提高字符识别的精度;
- 采用定位与识别一体化的算法。
■ 相关文献链接:
- AI Studio:中等规模的区段数码管数据集合
- 7Seg.zip:这是一个中等规模的七段数码管的数据集合。-网络攻防文档类资源-CSDN文库
● 相关图表链接:
- 图1.1.1 图片命名格式
- 图1.2.1 所有图片图片分割转换成灰度图片
- 图1.2.2 正反两种颜色,归一化之后的图像
- 图1.2.3 形成的数据库字符
- 图2.1.1 训练精度和测试精度
- 图2.1.2 模型识别错误的样本
- 图3.1 模型识别错误的样本
- 图3.1.1 识别为:1233
- 图3.1.2 识别为20143910
- 图3.2.1 重新搜集LCD数字
- 图3.2.2 识别成1234557890
- 图3.2.3 识别成1335
- 图3.2.4 测试LED图片
- 图3.3.2 识别成8881
- 图3.3.3 识别成01888038
- 图3.3.4 识别成8888
- 图3.3.5 识别成8888
- 图3.3.6 识别成2001
附件:识别程序
分割图片
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST1.PY -- by Dr. ZhuoQing 2022-01-03
#
# Note:
#============================================================
from headm import * # =
import cv2
from tqdm import tqdm
picdir = '/home/aistudio/work/7seg/7Seg'
filedim = [s for s in os.listdir(picdir) if s.upper().find('BMP') > 0 or s.upper().find('JPG') > 0]
filedim = sorted(filedim)
#printt(filedim)
#------------------------------------------------------------
outdir = '/home/aistudio/work/7seg/pic48'
totalpic = 0
OUT_SIZE = 48
for f in tqdm(filedim):
fn = os.path.join(picdir, f)
img = cv2.imread(fn)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# printt(gray.shape)
imgwidth = gray.shape[1]
imgheight = gray.shape[0]
numstr = f.split('.')[0].split('-')[1]
numnum = len(numstr)
for i in range(numnum):
left = imgwidth * i // numnum
right = imgwidth * (i + 1) // numnum
data = gray[0:imgheight, left:right]
dataout = cv2.resize(data, (OUT_SIZE, OUT_SIZE))
outfn = os.path.join(outdir, '%04d_%s.BMP'%(totalpic, numstr[i]))
totalpic += 1
cv2.imwrite(outfn, dataout)
newheight = int(imgheight * 0.85)
newwidth = int((right-left)*0.85)
deltaheight = (imgheight- newheight)//2
deltawidth = (right-left-newwidth)//2
data = gray[deltaheight:imgheight-deltaheight, left:right]
dataout = cv2.resize(data, (OUT_SIZE, OUT_SIZE))
outfn = os.path.join(outdir, '%04d_%s.BMP'%(totalpic, numstr[i]))
totalpic += 1
cv2.imwrite(outfn, dataout)
data = gray[0:imgheight, left+deltawidth:right-deltawidth]
dataout = cv2.resize(data, (OUT_SIZE, OUT_SIZE))
outfn = os.path.join(outdir, '%04d_%s.BMP'%(totalpic, numstr[i]))
totalpic += 1
cv2.imwrite(outfn, dataout)
data = gray[deltaheight:imgheight-deltaheight, left+deltawidth:right-deltawidth]
dataout = cv2.resize(data, (OUT_SIZE, OUT_SIZE))
outfn = os.path.join(outdir, '%04d_%s.BMP'%(totalpic, numstr[i]))
totalpic += 1
cv2.imwrite(outfn, dataout)
# printt(fn, outfn)
# break
printt(totalpic:)
#------------------------------------------------------------
# END OF FILE : TEST1.PY
#============================================================
图片归一化
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST1.PY -- by Dr. ZhuoQing 2022-01-03
#
# Note:
#============================================================
from headm import * # =
import paddle
import paddle.fluid as fluid
import paddle.nn.functional as F
from paddle import to_tensor as TT
import cv2
outdir = '/home/aistudio/work/7seg/pic48'
filedim = sorted([s for s in os.listdir(outdir) if s.find('BMP') > 0])
#printt(filedim)
#------------------------------------------------------------
picarray = []
labeldim = []
for f in filedim:
fn = os.path.join(outdir, f)
img = cv2.imread(fn)
gray = img[:,:,0]
gray = gray - mean(gray)
stdd = std(gray)
gray1 = gray / stdd
gray2 = gray * (-1.0)
# plt.clf()
# plt.figure(figsize=(10,10))
# plt.subplot(121)
# plt.axis("off")
# plt.imshow(gray1)
# plt.subplot(122)
# plt.axis("off")
# plt.imshow(gray2)
ff = f.split('.')[0].split('_')[-1]
if ff.isdigit():
ff = int(ff)
picarray.append(gray1)
picarray.append(gray2)
labeldim.append(ff)
labeldim.append(ff)
# break
#------------------------------------------------------------
printt(shape(picarray))
printt(labeldim)
outfile = '/home/aistudio/work/7seg/seg7_48_4.npz'
savez(outfile, pic=picarray, label=labeldim)
#------------------------------------------------------------
# END OF FILE : TEST1.PY
#============================================================
LCDNET
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST1.PY -- by Dr. ZhuoQing 2022-01-03
#
# Note:
#============================================================
from headm import * # =
import paddle
import paddle.fluid as fluid
from paddle import to_tensor as TT
from paddle.nn.functional import square_error_cost as SQRC
datafile = '/home/aistudio/work/7seg/seg7_48_4.npz'
data = load(datafile)
lcd = data['pic']
llabel = data['label']
printt(lcd.shape, llabel.shape)
#------------------------------------------------------------
dl = [(d,l) for d,l in zip(lcd, llabel)]
random.shuffle(dl)
printt(shape(dl))
train_ratio = 0.8
train_num = int(len(llabel) * train_ratio)
train_lcd = [a[0] for a in dl[:train_num]]
train_label = [a[1] for a in dl[:train_num]]
test_lcd = array([a[0] for a in dl[train_num:]])
test_label = array([a[1] for a in dl[train_num:]])
#------------------------------------------------------------
class Dataset(paddle.io.Dataset):
def __init__(self, num_samples):
super(Dataset, self).__init__()
self.num_samples = num_samples
def __getitem__(self, index):
data = train_lcd[index][newaxis,:,:]
label = train_label[index]
return paddle.to_tensor(data,dtype='float32'), paddle.to_tensor(label,dtype='int64')
def __len__(self):
return self.num_samples
_dataset = Dataset(len(train_label))
train_loader = paddle.io.DataLoader(_dataset, batch_size=200, shuffle=True)
#------------------------------------------------------------
test_d = paddle.to_tensor([a[newaxis,:,:] for a in test_lcd], dtype='float32')
test_l = paddle.to_tensor(test_label[:, newaxis], dtype='int64')
printt(shape(test_d):, shape(test_l):)
#------------------------------------------------------------
imgwidth = 48
imgheight = 48
inputchannel = 1
kernelsize = 5
targetsize = 10
ftwidth = ((imgwidth-kernelsize+1)//2-kernelsize+1)//2
ftheight = ((imgheight-kernelsize+1)//2-kernelsize+1)//2
class lenet(paddle.nn.Layer):
def __init__(self, ):
super(lenet, self).__init__()
self.conv1 = paddle.nn.Conv2D(in_channels=inputchannel, out_channels=6, kernel_size=kernelsize, stride=1, padding=0)
self.conv2 = paddle.nn.Conv2D(in_channels=6, out_channels=16, kernel_size=kernelsize, stride=1, padding=0)
self.mp1 = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
self.mp2 = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
self.L1 = paddle.nn.Linear(in_features=ftwidth*ftheight*16, out_features=120)
self.L2 = paddle.nn.Linear(in_features=120, out_features=86)
self.L3 = paddle.nn.Linear(in_features=86, out_features=targetsize)
def forward(self, x):
x = self.conv1(x)
x = paddle.nn.functional.relu(x)
x = self.mp1(x)
x = self.conv2(x)
x = paddle.nn.functional.relu(x)
x = self.mp2(x)
x = paddle.flatten(x, start_axis=1, stop_axis=-1)
x = self.L1(x)
x = paddle.nn.functional.relu(x)
# x = paddle.fluid.layers.dropout(x, 0.2)
x = self.L2(x)
x = paddle.nn.functional.relu(x)
x = self.L3(x)
return x
model = lenet()
#------------------------------------------------------------
optimizer = paddle.optimizer.Adam(learning_rate=0.001, parameters=model.parameters())
def train(model):
model.train()
epochs = 200
for epoch in range(epochs):
for batch, data in enumerate(train_loader()):
out = model(data[0])
loss = paddle.nn.functional.cross_entropy(out, data[1])
acc = paddle.metric.accuracy(out, data[1]).numpy()
preout = model(test_d)
test_acc = paddle.metric.accuracy(preout, test_l).numpy()
loss.backward()
optimizer.step()
optimizer.clear_grad()
printt('Epoch:{}, Accuracys:{}, Test:{}'.format(epoch, acc, test_acc))
train(model)
paddle.save(model.state_dict(), './work/seg7model.pdparams')
#------------------------------------------------------------
filename = '/home/aistudio/stdout.txt'
accdim = []
testdim = []
with open(filename, 'r') as f:
for l in f.readlines():
ll = l.split(':[')
if len(ll) < 3: continue
lacc = ll[-2].split(']')
if len(lacc) < 2: continue
accdim.append(float(lacc[0]))
tacc = ll[-1].split(']')
if len(tacc) < 2: continue
testdim.append(float(tacc[0]))
plt.figure(figsize=(12, 8))
plt.plot(accdim, label='Train ACC')
plt.plot(testdim, label='Test ACC')
plt.xlabel("Step")
plt.ylabel("Acc")
plt.grid(True)
plt.legend(loc='upper right')
plt.tight_layout()
plt.show()
#------------------------------------------------------------
# END OF FILE : TEST1.PY
#============================================================
测试程序
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST1.PY -- by Dr. ZhuoQing 2022-01-03
#
# Note:
#============================================================
from headm import * # =
import paddle
import paddle.fluid as fluid
import paddle
import paddle.fluid as fluid
from paddle import to_tensor as TT
from paddle.nn.functional import square_error_cost as SQRC
datafile = '/home/aistudio/work/7seg/seg7_48_4.npz'
data = load(datafile)
lcd = data['pic']
llabel = data['label']
printt(lcd.shape, llabel.shape)
test_d = paddle.to_tensor([a[newaxis,:,:] for a in lcd], dtype='float32')
test_l = paddle.to_tensor(llabel[:, newaxis], dtype='int64')
printt(shape(test_d):, shape(test_l):)
#------------------------------------------------------------
imgwidth = 48
imgheight = 48
inputchannel = 1
kernelsize = 5
targetsize = 10
ftwidth = ((imgwidth-kernelsize+1)//2-kernelsize+1)//2
ftheight = ((imgheight-kernelsize+1)//2-kernelsize+1)//2
class lenet(paddle.nn.Layer):
def __init__(self, ):
super(lenet, self).__init__()
self.conv1 = paddle.nn.Conv2D(in_channels=inputchannel, out_channels=6, kernel_size=kernelsize, stride=1, padding=0)
self.conv2 = paddle.nn.Conv2D(in_channels=6, out_channels=16, kernel_size=kernelsize, stride=1, padding=0)
self.mp1 = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
self.mp2 = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
self.L1 = paddle.nn.Linear(in_features=ftwidth*ftheight*16, out_features=120)
self.L2 = paddle.nn.Linear(in_features=120, out_features=86)
self.L3 = paddle.nn.Linear(in_features=86, out_features=targetsize)
def forward(self, x):
x = self.conv1(x)
x = paddle.nn.functional.relu(x)
x = self.mp1(x)
x = self.conv2(x)
x = paddle.nn.functional.relu(x)
x = self.mp2(x)
x = paddle.flatten(x, start_axis=1, stop_axis=-1)
x = self.L1(x)
x = paddle.nn.functional.relu(x)
# x = paddle.fluid.layers.dropout(x, 0.2)
x = self.L2(x)
x = paddle.nn.functional.relu(x)
x = self.L3(x)
return x
model = lenet()
model.set_state_dict(paddle.load('./work/seg7model.pdparams'))
#------------------------------------------------------------
preout = model(test_d)
preid = paddle.argmax(preout, axis=1).numpy()
test_acc = paddle.metric.accuracy(preout, test_l).numpy()
printt(test_acc)
printt(preid)
#------------------------------------------------------------
errid = where(llabel != preid)
printt(errid)
printt(len(errid[0]))
row_num = 4
col_num = 8
plt.figure(figsize=(12,8))
for i in range(row_num):
for j in range(col_num):
id = i*col_num+j
err = errid[0][id]
title = '%d->%d'%(llabel[err], preid[err])
plt.subplot(row_num, col_num, id+1)
plt.axis('off')
plt.title(title)
plt.imshow(lcd[err])
#------------------------------------------------------------
# END OF FILE : TEST1.PY
#============================================================
自动识别程序
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST1.PY -- by Dr. ZhuoQing 2022-01-03
#
# Note:
#============================================================
from headm import * # =
import paddle
import paddle.fluid as fluid
import cv2
#------------------------------------------------------------
imgwidth = 48
imgheight = 48
inputchannel = 1
kernelsize = 5
targetsize = 10
ftwidth = ((imgwidth-kernelsize+1)//2-kernelsize+1)//2
ftheight = ((imgheight-kernelsize+1)//2-kernelsize+1)//2
class lenet(paddle.nn.Layer):
def __init__(self, ):
super(lenet, self).__init__()
self.conv1 = paddle.nn.Conv2D(in_channels=inputchannel, out_channels=6, kernel_size=kernelsize, stride=1, padding=0)
self.conv2 = paddle.nn.Conv2D(in_channels=6, out_channels=16, kernel_size=kernelsize, stride=1, padding=0)
self.mp1 = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
self.mp2 = paddle.nn.MaxPool2D(kernel_size=2, stride=2)
self.L1 = paddle.nn.Linear(in_features=ftwidth*ftheight*16, out_features=120)
self.L2 = paddle.nn.Linear(in_features=120, out_features=86)
self.L3 = paddle.nn.Linear(in_features=86, out_features=targetsize)
def forward(self, x):
x = self.conv1(x)
x = paddle.nn.functional.relu(x)
x = self.mp1(x)
x = self.conv2(x)
x = paddle.nn.functional.relu(x)
x = self.mp2(x)
x = paddle.flatten(x, start_axis=1, stop_axis=-1)
x = self.L1(x)
x = paddle.nn.functional.relu(x)
# x = paddle.fluid.layers.dropout(x, 0.2)
x = self.L2(x)
x = paddle.nn.functional.relu(x)
x = self.L3(x)
return x
model = lenet()
model.set_state_dict(paddle.load('./work/seg7model4.pdparams'))
#------------------------------------------------------------
OUT_SIZE = 48
def pic2netinput(imgfile):
img = cv2.imread(imgfile)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
imgwidth = gray.shape[1]
imgheight = gray.shape[0]
f = os.path.basename(imgfile)
numstr = f.split('.')[0].split('-')[1]
numnum = len(numstr)
imgarray = []
labeldim = []
for i in range(numnum):
left = imgwidth * i // numnum
right = imgwidth * (i + 1) // numnum
data = gray[0:imgheight, left:right]
dataout = cv2.resize(data, (OUT_SIZE, OUT_SIZE))
dataout = dataout - mean(dataout)
stdd = std(dataout)
dataout = dataout / stdd
if numstr[i].isdigit():
imgarray.append(dataout[newaxis,:,:])
labeldim.append(int(numstr[i]))
test_i = paddle.to_tensor(imgarray, dtype='float32')
test_label = array(labeldim)
test_l = paddle.to_tensor(test_label[:, newaxis], dtype='int64')
return test_i, test_l
#------------------------------------------------------------
#picdir = '/home/aistudio/work/7seg/7Seg'
picdir = '/home/aistudio/work/7seg/testled'
filedim = [s for s in os.listdir(picdir) if s.upper().find('BMP') > 0 or s.upper().find('JPG') > 0]
filedim = sorted(filedim)
#------------------------------------------------------------
def checkimglabel(imgfile):
inp, label = pic2netinput(imgfile)
preout = model(inp)
preid = paddle.argmax(preout, axis=1).numpy().flatten()
label = label.numpy().flatten()
error = where(label != preid)[0]
return error, preid
#------------------------------------------------------------
for f in filedim:
imgfile = os.path.join(picdir, f)
error,id = checkimglabel(imgfile)
if len(error) > 0:
printt(error, f, id)
img = cv2.imread(imgfile)
plt.clf()
plt.figure(figsize=(8,8))
plt.axis("off")
plt.imshow(img)
plt.show()
#------------------------------------------------------------
# END OF FILE : TEST1.PY
#============================================================