1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
|
import sensor, time, image, pyb
from pyb import Pin
# 相机参数设置
sensor.reset() # 初始化相机
sensor.set_pixformat(sensor.GRAYSCALE) # 设置灰度像素模式,每个像素8bit
sensor.set_framesize(sensor.B128X128) # 设置图像大小,用于帧差异
sensor.set_windowing((92,112)) # 设置窗口ROI
sensor.skip_frames(10) # 跳过一些帧,等待感光元件变稳定
# 降低环境因素的影响
sensor.set_auto_gain(True) # 开启自动增益
sensor.set_auto_whitebal(True) # 开启自动白平衡
sensor.set_auto_exposure(True) # 开启自动曝光
# 定义IO口
# 输入引脚
p_in0 = Pin('P0', Pin.IN, Pin.PULL_UP) # 设置P0为“按键1”输入引脚,并开启上拉电阻
p_in1 = Pin('P1', Pin.IN, Pin.PULL_UP) # 设置P1为“按键2”输入引脚,并开启上拉电阻
p_in2 = Pin('P2', Pin.IN, Pin.PULL_UP) # 设置P2为“按键3”输入引脚,并开启上拉电阻
p_in3 = Pin('P3', Pin.IN, Pin.PULL_UP) # 设置P3为“按键4”输入引脚,并开启上拉电阻
# 输出引脚
RED_LED_PIN = 1 # 红色LED输出引脚
GREEN_LED_PIN = 2 # 绿色LED输出引脚
BLUE_LED_PIN = 3 # 蓝色LED输出引脚
p_out0 = Pin('P4', Pin.OUT_PP) # 设置p_out为输出引脚
p_out1 = Pin('P5', Pin.OUT_PP) # 设置p_out为输出引脚
p_out2 = Pin('P6', Pin.OUT_PP) # 设置p_out为输出引脚
p_out3 = Pin('P7', Pin.OUT_PP) # 设置p_out为输出引脚
# 定义全局变量
face_result = 0 #身份识别结果
mask_result = 0 #口罩判别结果
iden_out_result = 0 #学习后识别结果
# 功能部分
while(True):
# 读取输入引脚数值
value0 = p_in0.value() # 读入p_in0引脚的值
value1 = p_in1.value() # 读入p_in1引脚的值
value2 = p_in2.value() # 读入p_in2引脚的值
value3 = p_in3.value() # 读入p_in3引脚的值
# 定义变量
face_num0 = 0
face_num1 = 0
face_num2 = 0
mask_num0 = 0
mask_num1 = 0
mask_num2 = 0
iden_in_num0 = 0
iden_in_num1 = 0
iden_in_num2 = 0
iden_out_num0 = 0
iden_out_num1 = 0
iden_out_num2 = 0
# 判断输入引脚数值
if value2 == 0: # 第3个按键按下时,开启学习模式
print("开启学习模式")
p_out0.low() # 0010 第3个灯亮 表示第3个按键被按下
p_out1.low()
p_out2.high()
p_out3.low()
sensor.skip_frames(time = 500) # 延时0.5s
p_out0.low() # 将4个输出IO口全部置低电平(不然灯会一直亮着)
p_out1.low()
p_out2.low()
p_out3.low()
if value0 == 0: # 第1个按键按下时,学习第1个人
print("正在学习第1个人脸")
#设置识别数量
iden_in_num0 = 1 # 设置被拍摄者序号,第一个人的图片保存到i1文件夹,第二个人的图片保存到i2文件夹,以此类推。每次更换拍摄者时,修改num值
n = 5 # 拍摄照片数量
while(n):
pyb.LED(RED_LED_PIN).on() # 红灯亮
sensor.skip_frames(time = 3000) # 延时3s
pyb.LED(RED_LED_PIN).off() # 红灯灭
pyb.LED(BLUE_LED_PIN).on() # 蓝灯亮
# 保存截取到的图片到SD卡
print(n)
sensor.snapshot().save("identify/i%s/%s.pgm" % (iden_in_num0, n) ) # 此处会被保存于"identify/i1/"
n -= 1
pyb.LED(BLUE_LED_PIN).off() # 蓝灯灭
break
if value1 == 0: # 第2个按键按下时,学习第2个人
print("正在学习第2个人脸")
iden_in_num1 = 2 # 设置被拍摄者序号,第一个人的图片保存到i1文件夹,第二个人的图片保存到i2文件夹,以此类推。每次更换拍摄者时,修改num值
n = 5 # 拍摄照片数量
while(n):
pyb.LED(RED_LED_PIN).on() # 红灯亮
sensor.skip_frames(time = 3000) # 延时3s
pyb.LED(RED_LED_PIN).off() # 红灯灭
pyb.LED(BLUE_LED_PIN).on() # 蓝灯亮
# 保存截取到的图片到SD卡
print(n)
sensor.snapshot().save("identify/i%s/%s.pgm" % (iden_in_num1, n) ) # 此处会被保存于"identify/i2/"
n -= 1
pyb.LED(BLUE_LED_PIN).off() # 蓝灯灭
break
if value3 == 0: # 第4个按键按下时,学习第3个人(因为第3个按键需长按,保持P6在低电平状态,才能执行之后的程序)
print("正在学习第3个人脸")
iden_in_num2 = 3 # 设置被拍摄者序号,第一个人的图片保存到i1文件夹,第二个人的图片保存到i2文件夹,以此类推。每次更换拍摄者时,修改num值
n = 5 # 拍摄照片数量
while(n):
pyb.LED(RED_LED_PIN).on() # 红灯亮
sensor.skip_frames(time = 3000) # 延时3s
pyb.LED(RED_LED_PIN).off() # 红灯灭
pyb.LED(BLUE_LED_PIN).on() # 蓝灯亮
# 保存截取到的图片到SD卡
print(n)
sensor.snapshot().save("identify/i%s/%s.pgm" % (iden_in_num2, n) ) # 此处会被保存于"identify/i3/"
n -= 1
pyb.LED(BLUE_LED_PIN).off() # 蓝灯灭
break
if value3 == 0: # 第4个按键单独按下时,开启学习后识别模式
print("正在开启学习后识别模式")
p_out0.low() # 0001 第4个灯亮 表示第4个按键被按下
p_out1.low()
p_out2.low()
p_out3.high()
sensor.skip_frames(time = 500) #延时0.5s
p_out0.low() # 将4个输出IO口全部置低电平
p_out1.low()
p_out2.low()
p_out3.low()
#设置样本数量
NUM_SUBJECTS = 3 # 图像库总人数
NUM_SUBJECTS_IMGS = 5 # 样本图片数量
for iden in range(3): # 循环拍摄3次样本图片,进行比对,输出出现次数最多的结果
# 拍摄当前人脸
sensor.skip_frames(time = 3000) # 等待3s
img = sensor.snapshot() # 拍照
d0 = img.find_lbp((11,14,70,84)) # 当前拍摄人脸的lbp特征,将识别ROI区域往内缩小1/8,避免一定程度上背景带来的影响
img = None
pmin = 999999 # pmin为最小特征差异度
iden_out_num=0
def min(pmin, a, s): # 确保几次循环后pmin还是最小特征差异度,a代表dist/NUM_SUBJECTS_IMGS
global iden_out_num
if a<pmin:
pmin=a
iden_out_num=s
return pmin
for s in range(1, NUM_SUBJECTS+1):
dist = 0
for i in range(2, NUM_SUBJECTS_IMGS+1):
img = image.Image("identify/i%s/%s.pgm"%(s, i))
d1 = img.find_lbp((11,14,70,84)) # d1为第s文件夹中的第i张图片的lbp特征,识别ROI区域往内缩小1/8
dist += image.match_descriptor(d0, d1) # 计算d0 d1即样本图像与被检测人脸的特征差异度。
print("第%d个的特征差异度是: %d"%(s, dist/NUM_SUBJECTS_IMGS)) # 输出当前特征差异度,方便在串口终端显示数据
pmin = min(pmin, dist/NUM_SUBJECTS_IMGS, s) # 特征差异度越小,被检测人脸与此样本更相似更匹配。
print(pmin)
# 按照循环次数,将每次识别后的结果存入,共3次
if iden == 0:
iden_out_num0 = iden_out_num
print("第%d次:%d"%(iden+1,iden_out_num0))
if iden == 1:
iden_out_num1 = iden_out_num
print("第%d次:%d"%(iden+1,iden_out_num1))
if iden == 2:
iden_out_num2 = iden_out_num
print("第%d次:%d"%(iden+1,iden_out_num2))
pyb.LED(BLUE_LED_PIN).on() # 蓝灯亮
sensor.skip_frames(time = 50) # 等待0.05s
pyb.LED(BLUE_LED_PIN).off() # 蓝灯灭
# 在此处对3次输出结果进行比较,输出出现次数最多的那个结果。如果三个分别为不同结果,则报错。
if iden_out_num0 == iden_out_num1 == iden_out_num2:
print("结果是:",iden_out_num0)
iden_out_result = iden_out_num0
else:
if iden_out_num0 == iden_out_num1:
print("结果是:",iden_out_num0)
iden_out_result = iden_out_num0
if iden_out_num0 == iden_out_num2:
print("结果是:",iden_out_num0)
iden_out_result = iden_out_num0
if iden_out_num1 == iden_out_num2:
print("结果是:",iden_out_num1)
iden_out_result = iden_out_num1
#else: #不知道为什么有时候有相同结果时也会报错,故此处屏蔽该段代码,下同
# print("error")
# iden_out_result = 15
if value0 == 0: # 第1个按键单独按下时,开启身份识别模式
print("正在开启身份识别模式")
p_out0.high() # 0001 第1个灯亮 表示第1个按键被按下
p_out1.low()
p_out2.low()
p_out3.low()
sensor.skip_frames(time = 500) # 延时0.5s
p_out0.low() # 将4个输出IO口全部置低电平
p_out1.low()
p_out2.low()
p_out3.low()
#设置样本数量
NUM_SUBJECTS = 3 # 图像库总人数
NUM_SUBJECTS_IMGS = 5 # 样本图片数量
for face in range(3):
# 拍摄当前人脸
sensor.skip_frames(time = 3000) # 等待3s
img = sensor.snapshot() # 拍照
d0 = img.find_lbp((11,14,70,84)) # 当前拍摄人脸的lbp特征,将识别ROI区域往内缩小1/8
img = None
pmin = 999999 # pmin为最小特征差异度
face_num=0
def min(pmin, a, s): # 确保几次循环后pmin还是最小特征差异度,a代表dist/NUM_SUBJECTS_IMGS
global face_num
if a<pmin:
pmin=a
face_num=s
return pmin
for s in range(1, NUM_SUBJECTS+1):
dist = 0
for i in range(2, NUM_SUBJECTS_IMGS+1):
img = image.Image("face/f%d/%d.pgm"%(s, i))
d1 = img.find_lbp((11,14,70,84)) # d1为第s文件夹中的第i张图片的lbp特征,识别ROI区域往内缩小1/8
dist += image.match_descriptor(d0, d1) # 计算d0 d1即样本图像与被检测人脸的特征差异度。
print("Average dist for subject %d: %d"%(s, dist/NUM_SUBJECTS_IMGS)) # 输出当前特征差异度,方便在串口终端显示数据
pmin = min(pmin, dist/NUM_SUBJECTS_IMGS, s) # 特征差异度越小,被检测人脸与此样本更相似更匹配。
print(pmin)
# 按照循环次数,将每次识别后的结果存入,共3次
if face == 0:
face_num0 = face_num
print("第%d次:%d"%(face+1,face_num0))
if face == 1:
face_num1 = face_num
print("第%d次:%d"%(face+1,face_num1))
if face == 2:
face_num2 = face_num
print("第%d次:%d"%(face+1,face_num2))
pyb.LED(RED_LED_PIN).on() # 红灯亮
sensor.skip_frames(time = 50) # 等待0.05s
pyb.LED(RED_LED_PIN).off() # 红灯灭
# 在此处对3次输出结果进行比较,输出出现次数最多的那个结果。如果三个分别为不同结果,则报错。
if face_num0 == face_num1 == face_num2:
print("结果是:",face_num0)
face_result = face_num0
else:
if face_num0 == face_num1:
print("结果是:",face_num0)
face_result = face_num0
if face_num0 == face_num2:
print("结果是:",face_num0)
face_result = face_num0
if face_num1 == face_num2:
print("结果是:",face_num1)
face_result = face_num1
#else:
# print("error")
# face_result = 15
if value1 == 0: # 第2个按键单独按下时,开启口罩判别模式
print("正在开启口罩判别模式")
p_out0.low() # 0100 第2个灯亮 表示第2个按键被按下
p_out1.high()
p_out2.low()
p_out3.low()
sensor.skip_frames(time = 500) # 延时0.5s
p_out0.low() # 将4个输出IO口全部置低电平
p_out1.low()
p_out2.low()
p_out3.low()
#设置样本数量
NUM_SUBJECTS = 3 # 图像库总人数
NUM_SUBJECTS_IMGS = 5 # 样本图片数量
for mask in range(3):
# 拍摄当前人脸。
sensor.skip_frames(time = 3000) # 等待3s
img = sensor.snapshot() # 拍照
d0 = img.find_lbp((11,14,70,84)) # 当前拍摄人脸的lbp特征,将识别ROI区域往内缩小1/8
img = None
pmin = 999999 # pmin为最小特征差异度
mask_num=0
def min(pmin, a, s): # 确保几次循环后pmin还是最小特征差异度,a代表dist/NUM_SUBJECTS_IMGS
global mask_num
if a<pmin:
pmin=a
mask_num=s
return pmin
for s in range(1, NUM_SUBJECTS+1):
dist = 0
for i in range(2, NUM_SUBJECTS_IMGS+1):
img = image.Image("mask/m%d/%d.pgm"%(s, i))
d1 = img.find_lbp((11,14,70,84)) # d1为第s文件夹中的第i张图片的lbp特征,识别ROI区域往内缩小1/8
dist += image.match_descriptor(d0, d1) # 计算d0 d1即样本图像与被检测人脸的特征差异度。
print("Average dist for subject %d: %d"%(s, dist/NUM_SUBJECTS_IMGS)) # 输出当前特征差异度,方便在串口终端显示数据
pmin = min(pmin, dist/NUM_SUBJECTS_IMGS, s) # 特征差异度越小,被检测人脸与此样本更相似更匹配。
print(pmin)
# 按照循环次数,将每次识别后的结果存入,共3次
if mask == 0:
mask_num0 = mask_num
print("第%d次:%d"%(mask+1,mask_num0))
if mask == 1:
mask_num1 = mask_num
print("第%d次:%d"%(mask+1,mask_num1))
if mask == 2:
mask_num2 = mask_num
print("第%d次:%d"%(mask+1,mask_num2))
pyb.LED(GREEN_LED_PIN).on() # 绿灯亮
sensor.skip_frames(time = 50) # 等待0.05s
pyb.LED(GREEN_LED_PIN).off() #绿灯灭
# 在此处对3次输出结果进行比较,输出出现次数最多的那个结果。如果三个分别为不同结果,则报错。
if mask_num0 == mask_num1 == mask_num2:
print("结果是:",mask_num0)
mask_result = mask_num0
else:
if mask_num0 == mask_num1:
print("结果是:",mask_num0)
mask_result = mask_num0
if mask_num0 == mask_num2:
print("结果是:",mask_num0)
mask_result = mask_num0
if mask_num1 == mask_num2:
print("结果是:",mask_num1)
mask_result = mask_num1
#else:
#print("error")
# 此处为输出IO口高低电平定义,具体请参照附表
# 身份识别结果输出
if face_result == 1:#1000
print("face_num1",face_result)
p_out0.high()
p_out1.low()
p_out2.low()
p_out3.low()
if face_result == 2:#0100
print("face_num2",face_result)
p_out0.low()
p_out1.high()
p_out2.low()
p_out3.low()
if face_result == 3:#0010
print("face_num3",face_result)
p_out0.low()
p_out1.low()
p_out2.high()
p_out3.low()
if face_result == 15:#1111
print("error",face_result)
p_out0.high()
p_out1.high()
p_out2.high()
p_out3.high()
# 口罩判别结果输出
if mask_result == 1:#0011
print("mask_num1",mask_result)
p_out0.low()
p_out1.low()
p_out2.high()
p_out3.high()
if mask_result == 2:#1100
print("mask_num2",mask_result)
p_out0.high()
p_out1.high()
p_out2.low()
p_out3.low()
if mask_result == 15:#1111
print("error",mask_result)
p_out0.high()
p_out1.high()
p_out2.high()
p_out3.high()
# 学习后识别结果输出
if iden_out_result == 1:#0100
print("iden_out_num1",iden_out_result)
p_out0.low()
p_out1.high()
p_out2.low()
p_out3.low()
if iden_out_result == 2:#0010
print("iden_out_num2",iden_out_result)
p_out0.low()
p_out1.low()
p_out2.high()
p_out3.low()
if iden_out_result == 3:#0001
print("iden_out_num3",iden_out_result)
p_out0.low()
p_out1.low()
p_out2.low()
p_out3.high()
if iden_out_result == 15:#1111
print("error",iden_out_result)
p_out0.high()
p_out1.high()
p_out2.high()
p_out3.high()
|