一、硬件
用的K210 maixduino
上边搭载了一个ESP32
脸子姐的APP,开干
二、流程
先把这个模块(文件上传到开发板)注意里面的I/O,如果自己改过默认的I/O需要在这个文件里面改一下,就是和ESP32通讯的那个
import time, network
from Maix import GPIO
from fpioa_manager import fm
class wifi():
nic = None
def reset(force=False, reply=5, is_hard=True):
if force == False and __class__.isconnected():
return True
try:
# IO map for ESP32 on Maixduino
fm.register(25,fm.fpioa.GPIOHS10)#cs
fm.register(8,fm.fpioa.GPIOHS11)#rst
fm.register(9,fm.fpioa.GPIOHS12)#rdy
if is_hard:
print("Use Hareware SPI for other maixduino")
fm.register(28,fm.fpioa.SPI1_D0, force=True)#mosi
fm.register(26,fm.fpioa.SPI1_D1, force=True)#miso
fm.register(27,fm.fpioa.SPI1_SCLK, force=True)#sclk
__class__.nic = network.ESP32_SPI(cs=fm.fpioa.GPIOHS10, rst=fm.fpioa.GPIOHS11, rdy=fm.fpioa.GPIOHS12, spi=1)
print("ESP32_SPI firmware version:", __class__.nic.version())
else:
# Running within 3 seconds of power-up can cause an SD load error
print("Use Software SPI for other hardware")
fm.register(28,fm.fpioa.GPIOHS13, force=True)#mosi
fm.register(26,fm.fpioa.GPIOHS14, force=True)#miso
fm.register(27,fm.fpioa.GPIOHS15, force=True)#sclk
__class__.nic = network.ESP32_SPI(cs=fm.fpioa.GPIOHS10,rst=fm.fpioa.GPIOHS11,rdy=fm.fpioa.GPIOHS12, mosi=fm.fpioa.GPIOHS13,miso=fm.fpioa.GPIOHS14,sclk=fm.fpioa.GPIOHS15)
print("ESP32_SPI firmware version:", __class__.nic.version())
# time.sleep_ms(500) # wait at ready to connect
except Exception as e:
print(e)
return False
return True
def connect(ssid="wifi_name", pasw="pass_word"):
if __class__.nic != None:
return __class__.nic.connect(ssid, pasw)
def ifconfig(): # should check ip != 0.0.0.0
if __class__.nic != None:
return __class__.nic.ifconfig()
def isconnected():
if __class__.nic != None:
return __class__.nic.isconnected()
return False
if __name__ == "__main__":
# It is recommended to callas a class library (upload network_espat.py)
# from network_esp32 import wifi
SSID = "OnePlus 6"
PASW = "123456789"
def check_wifi_net(reply=5):
if wifi.isconnected() != True:
for i in range(reply):
try:
wifi.reset(is_hard=True)
print('try AT connect wifi...')
wifi.connect(SSID, PASW)
if wifi.isconnected():
break
except Exception as e:
print(e)
return wifi.isconnected()
if wifi.isconnected() == False:
check_wifi_net()
print('network state:', wifi.isconnected(), wifi.ifconfig())
# The network is no longer configured repeatedly
import socket
sock = socket.socket()
# your send or recv
# see other demo_socket_tcp.py / udp / http / mqtt
sock.close()
三、程序
SSID = "esp82666" #手机热点名称需要更改成自己手机的,打开手机热点再打开aap即可使用
PASW = "12345678" #手机热点密码
ADDR =['192.168.43.95',56050] #ip地址和端口号(端口号安卓端写死的56050不能更改)
def enable_esp32(): ###如果是Maixduino板使能该方法,将network_esp32.py发送到板子上
global ADDR
from network_esp32 import wifi
if True:
for i in range(5):
try:
wifi.reset(is_hard=True)
print('try AT connect wifi...')
wifi.connect(SSID, PASW)
if wifi.isconnected():
ADDR[0]=wifi.ifconfig()[2]
break
except Exception as e:
print(e)
print('network state:', wifi.isconnected(), wifi.ifconfig())
enable_esp32() #连接安卓端的wifi
import socket
sock = socket.socket()#socket连接到安卓端的服务器
sock.connect(ADDR)
sock.settimeout(1)
import sensor,image,lcd,time,gc
import KPU as kpu
import time
from Maix import FPIOA, GPIO
import gc
from fpioa_manager import fm
from board import board_info
import utime
#**********头文件啊*************************
lcd.init(freq=15000000)
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_vflip(0)
sensor.set_hmirror(1)
clock = time.clock()
lcd.rotation(2)
#******************串口定义*******************
from fpioa_manager import fm
fm.register(21, fm.fpioa.UART1_TX, force=True)
fm.register(22, fm.fpioa.UART1_RX, force=True)
from machine import UART
uart = UART(UART.UART1, 9600, 8, 0, 0, timeout=1000, read_buf_len=4096)
#******************加载模型分别是196特征值和mask(口罩和人脸)********************
task_fe = kpu.load(0x500000)
task = kpu.load(0x300000)
#******************加载模型分别是196特征值和mask(口罩和人脸)********************
anchor = (1.889, 2.5245, 2.9465, 3.94056, 3.99987, 5.3658, 5.155437, 6.92275, 6.718375, 9.01025)
dst_point = [(44, 59), (84, 59), (64, 82), (47, 105),
(81, 105)] # standard face key point position
a = kpu.init_yolo2(task, 0.5, 0.3, 5, anchor)
b = kpu.init_yolo2(task_fe, 0.5, 0.3, 5, anchor)
#******************人脸特征值储存********************
record_ftr = []
record_ftrs = [b'\x02\xc9\xe3\x00\xc2\x12\xe7t\xd9\x80y\x0e\xfe\xeb\x1a\xdf\t\xa9\xc2\xed\x80\xb4\x0f\xd0\x99l\x9d\xb0\xa5e\xc0\x80\x00\x1d\n\x808\x80\x05\xb2\xa9R3\x80\x01\xaa<\x15+\xb5\xfb\x80\xd7\x80"\xde\xb0/\x0e\xda\x9c6\xce\xeaJ\xf7\xde\x17\x1bc\xb1\xd6T\xf3\xf9\x03\x9b3V\xc9\x17\x19\x80\xde\xf7\x80@\x80\r\xbe\xdd\xf2\xd9\xce7\x9d\x15\xc5\x8c+\x01\x95L\xf2\x1d!tR\xd0\xb62\x06?\x13\xa3\xe2"\x0b\x13\x01\x80\x13\x80\xbc8\xe6[\xce\x83\xaa\x80.\xbc\n`\xfaF\x0ex\xcd-*K@F\x80#\xe3\x80\xbd\xc8\xfd.\xe3\x13\xd6\xdfJ\x1e\x80\x17#\xbe\x85\x00\xbcG\x97\xad\xf2\xc1\x1a\xc9\x1e\xea\xcd\x1b6\xae\xd7\xc4\xce\xc1+\xe5\x03\x80\x0e\x83\xeb#\xfe\x0e\xc9C\xff',
b'\xb86\x032X\x97\x17W\x02{\n\xd5\xba!\xc6\xda\x0b\xd7\xa1\xef\x00\x80c8\x07\x0b\x80<\xfd\xd0\xdd\x12\xb2]\x80\x05\x80\xea&T\xe57\x07B\xee\x01\x88%?\xdf.)\xed\xd0/\t\xd1\r\x8b\xee\xd0\xddF\xe1\x9c\x12\xe5\x1fS\r;\x1a\xf5\x0f\xbe\xe2\xb6#3\x11s\x03\xb4S\x05\x1a\xe3\xc8\xda\x16\xbd\xccJ\x05\xcet\xeb\xfb!\xad\xb2\xa9\x1a<:>\xd2\xf7\xf3\xef\xa1\x1e\xff\xe2\xed\xfd\xf1+"\xd2\xf6RW\x80o&x\x80\xe2\x03\x80\xd2\xeaG\xba\xed/\xda\x1a\xfa\xce_\xb6\x12B\xbaK\xfb\xf6\xe1\xfb\xda\xd3|\xc5\xb4\xed\xbcu\x80\xda\x80d\x06>\xf5\xf3\xba\xee\xdd\xdd\x80\xc0du!\x90\x0f\xc1J\x99\xb9\xad\xdd\xfd*\'\x80\x1eG\x1b\x80\x80\xda"\xa6',
b"\x00\x03\xda\xe5`\x91\xd5\x1a\x1f4'\xca!\xd1;\x8d\xfe\x8f4\x13\xe9\x9d8\xba\x1e4\xde\x02\xe5\xc9\xc9>W\x03)\xadh%&\xe9\xea#\x13\xf1\t&\xc9\xfa2\xcaX\x00\xd9\xe1J\xc88\xf5\x85\x0b\xe7\xcd\x01&\x13\xd0\xf6D2\xfb.\xe3\xd26\xd1\xf2\xf7\tF\x02\xff\x07\xe7\xde\x162\x0fo\xb5\xbe\x98\xf9\x12\x13\xd3\xe9\xc200\xdb\x0e\xc1\xe2\xfal\xf3\x11C\xc1\xf1\xaa\xe9*\xf1>\xfe\xe5\x17\x077\x0f\xe1\x94\xa1\xfa\x1dw\x19N\xc5\xdfa\x11\x12\xeb\x1f!\xf3\xe9\x07\xd57\x00\xfeT\xac\xd5\x80\xdd\xff\x162\x06\xda?\xf3+\xb9\x12\xfd\xeb\x01\xf3\x80N+\x15\xdbd\x97\x06\xaa)S\x8c\xf1\xd0-\xdf\xda\x80\x80\xef0\xe2\xbate\x0f8\xd1\xac\xf1\xb9/\xd6"
]
names = ['1', '2', '3', 'QZH', 'QZH','QZH', 'ZPZ', 'ZPZ', 'ZPZ', 'Mr.10']
#******************人脸相似度********************
ACCURACY = 70
#******************定义boot按键********************
fm.register(board_info.BOOT_KEY, fm.fpioa.GPIOHS0)
key_gpio = GPIO(GPIO.GPIOHS0, GPIO.IN)
#******************中断函数********************
start_processing = False
BOUNCE_PROTECTION = 50
def set_key_state(*_):
global start_processing
start_processing = True
utime.sleep_ms(BOUNCE_PROTECTION)
key_gpio.irq(set_key_state, GPIO.IRQ_RISING, GPIO.WAKEUP_NOT_SUPPORT)
#**************变量*****************#
data=bytearray([0xFF,0xFF,0xFF])
A_1=A_2=0
B_1=B_2=B_3=B_4=0
j_1=j_4=0
j_2=j_3=1
a=bytearray([0,0,0,0,0,0,1,255,1,255]) #图片帧尾每发送一张图片就会发送一次该数组,数组后四位是固定的不能更改,安卓端接收到这四位
#判断一帧结束,前六位用来存放传感的测量数据或识别的标志位,安卓端可以解析出来进行相应的显示
#如果只是用来图传默认为0就行了
while True:
img = sensor.snapshot() #摄像头采集一张图片
#'''
code = kpu.run_yolo2(task, img)
if code:
totalRes = len(code)
for item in code:
img.draw_rectangle(item.rect())
##******************图片转换********************
face_cut = img.cut(item.x(), item.y(), item.w(), item.h())
face_cut_128 = face_cut.resize(128, 128)
face_cut_128.pix_to_ai()
del (face_cut)
#******************人脸********************
fmap = kpu.forward(task_fe, face_cut_128)
feature = kpu.face_encode(fmap[:])
reg_flag = False
scores = []
for j in range(len(record_ftrs)):
score = kpu.face_compare(record_ftrs[j], feature)
scores.append(score)
max_score = 0
index = 0
del (face_cut_128)
for k in range(len(scores)):
if max_score < scores[k]:
max_score = scores[k]
index = k
if max_score > ACCURACY:
img.draw_string(item.x(), item.y(), ("%s :%2.1f" % (
names[index], max_score)), color=(0, 255, 0), scale=2)
if(index==0):
B_1=B_1+1
B_2=B_3=0
if(B_1==10):
uart.write("n0.val=1")
uart.write(data)
B_1=0
if(index==1):
B_2=B_2+1
B_1=B_3=0
if(B_2==10):
print("识别到了:" ,index)
uart.write("n0.val=2")
uart.write(data)
B_2=0
if(index==2):
B_3=B_3+1
B_2=B_1=0
if(B_3==10):
print("识别到了:" ,index)
uart.write("n0.val=3")
uart.write(data)
B_3=0
#print("识别到了:" ,index)
else:
img.draw_string(item.x(), item.y(), ("X :%2.1f" % (
max_score)), color=(255, 0, 0), scale=2)
B_4=B_4+1
if(B_4==10):
print("未注册")
uart.write("n0.val=4")
uart.write(data)
B_4=0
#***********************按键注册*******************
if start_processing:
record_ftrs = []
record_ftr = feature
record_ftrs.append(record_ftr)
print(feature)
uart.write(str(feature))
start_processing = False
break
lcd.display(img)
img = img.compress(quality=50) #压缩图片提升传输速率,想要图像更清晰将quality调大一些(quality范围在0~100)
img_bytes = img.to_bytes() #将图片转成字节数组
del(img)
try: #esp32寄存器大小有限 将图片分段发送可以避免通过esp32发送出现数据丢失的问题
block = int(len(img_bytes)/2048)
for i in range(block):
send_len = sock.send(img_bytes[i*2048:(i+1)*2048])
time.sleep_ms(1)
send_len2 = sock.send(img_bytes[block*2048:])
time.sleep_ms(1)
sock.send(a) #发送完图片发送一次帧结尾数组
except OSError as e:
if e.args[0] == 128:
print("connection closed")
sock.connect(ADDR) #socket意外断开时进行重新连接
continue
except Exception as e:
print("send fail:", e)
time.sleep(1)
sock.connect(ADDR) #socket意外断开时进行重新连接
continue
time.sleep_us(1)
gc.collect()
a = kpu.deinit(task)
a = kpu.deinit(task_fe)
第一次连接要把串口打印出得IP复制到上面去