本次通过安信可小安派BW21-CBV-Kit+热敏打印模块开发一款纸质出入记录器。可以通过人脸识别确认出入人员,并实时对出入记录进行打印。
在淘宝选择了一款热敏打印模块,这里就不贴链接和店铺了,大家可以根据需求自行选配

根据热敏打印模块的官方说明,可使用TTL、RS232、USB三种模式进行连接。我选择的是TTL连接的BW21-CBV-Kit

根据安信可小安派BW21-CBV-Kit官方资料(https://fcniufr8ibx1.feishu.cn/wiki/RJ9pw7PsRieLu2k257FcO2hzn9b)

IOA2及IOA3对应UART1_TXD及UART1_RXD。用IOA2通过排线连接热敏打印模块RXD,IOA3通过排线连接热敏打印模块TXD,便完成了最基本的硬件连接连接。
以下为实物连接方式


为使安信可小安派BW21-CBV-Kit可以正常输出内容,需要初始化Serial1.begin(115200);同时当检测到人脸时Serial1.println(item.name());
完整代码如下:
/*
Example guide:
https://www.amebaiot.com/en/amebapro2-arduino-neuralnework-face-recognition/
Face registration commands
--------------------------
Point the camera at a target face and enter the following commands into the serial monitor,
Register face: "REG={Name}" Ensure that there is only one face detected in frame
Remove face: "DEL={Name}" Remove a registered face
Reset registered faces: "RESET" Forget all previously registered faces
Backup registered faces to flash: "BACKUP" Save registered faces to flash
Restore registered faces from flash: "RESTORE" Load registered faces from flash
NN Model Selection
-------------------
Select Neural Network(NN) task and models using modelSelect(nntask, objdetmodel, facedetmodel, facerecogmodel).
Replace with NA_MODEL if they are not necessary for your selected NN Task.
NN task
=======
OBJECT_DETECTION/ FACE_DETECTION/ FACE_RECOGNITION
Models
=======
YOLOv3 model DEFAULT_YOLOV3TINY / CUSTOMIZED_YOLOV3TINY
YOLOv4 model DEFAULT_YOLOV4TINY / CUSTOMIZED_YOLOV4TINY
YOLOv7 model DEFAULT_YOLOV7TINY / CUSTOMIZED_YOLOV7TINY
SCRFD model DEFAULT_SCRFD / CUSTOMIZED_SCRFD
MobileFaceNet model DEFAULT_MOBILEFACENET/ CUSTOMIZED_MOBILEFACENET
No model NA_MODEL
*/
#include "WiFi.h"
#include "StreamIO.h"
#include "VideoStream.h"
#include "RTSP.h"
#include "NNFaceDetectionRecognition.h"
#include "VideoStreamOverlay.h"
#define CHANNEL 0
#define CHANNELNN 3
// Customised resolution for NN
#define NNWIDTH 576
#define NNHEIGHT 320
VideoSetting config(VIDEO_FHD, 30, VIDEO_H264, 0);
VideoSetting configNN(NNWIDTH, NNHEIGHT, 10, VIDEO_RGB, 0);
NNFaceDetectionRecognition facerecog;
RTSP rtsp;
StreamIO videoStreamer(1, 1);
StreamIO videoStreamerFDFR(1, 1);
StreamIO videoStreamerRGBFD(1, 1);
char ssid[] = "SSID"; // your network SSID (name)
char pass[] = "password"; // your network password
int status = WL_IDLE_STATUS;
String Last = " ";
IPAddress ip;
int rtsp_portnum;
void setup()
{
Serial.begin(115200);
Serial1.begin(115200);
// Attempt to connect to Wifi network:
while (status != WL_CONNECTED) {
//Serial.print("Attempting to connect to WPA SSID: ");
//Serial.println(ssid);
status = WiFi.begin(ssid, pass);
// wait 2 seconds for connection:
delay(2000);
}
ip = WiFi.localIP();
// Configure camera video channels with video format information
// Adjust the bitrate based on your WiFi network quality
config.setBitrate(2 * 1024 * 1024); // Recommend to use 2Mbps for RTSP streaming to prevent network congestion
Camera.configVideoChannel(CHANNEL, config);
Camera.configVideoChannel(CHANNELNN, configNN);
Camera.videoInit();
// Configure RTSP with corresponding video format information
rtsp.configVideo(config);
rtsp.begin();
rtsp_portnum = rtsp.getPort();
// Configure Face Recognition model
// Select Neural Network(NN) task and models
facerecog.configVideo(configNN);
facerecog.modelSelect(FACE_RECOGNITION, NA_MODEL, DEFAULT_SCRFD, DEFAULT_MOBILEFACENET);
facerecog.begin();
facerecog.setResultCallback(FRPostProcess);
// Configure StreamIO object to stream data from video channel to RTSP
videoStreamer.registerInput(Camera.getStream(CHANNEL));
videoStreamer.registerOutput(rtsp);
if (videoStreamer.begin() != 0) {
//Serial.println("StreamIO link start failed");
}
// Start data stream from video channel
Camera.channelBegin(CHANNEL);
// Configure StreamIO object to stream data from RGB video channel to face detection
videoStreamerRGBFD.registerInput(Camera.getStream(CHANNELNN));
videoStreamerRGBFD.setStackSize();
videoStreamerRGBFD.setTaskPriority();
videoStreamerRGBFD.registerOutput(facerecog);
if (videoStreamerRGBFD.begin() != 0) {
//Serial.println("StreamIO link start failed");
}
// Start video channel for NN
Camera.channelBegin(CHANNELNN);
// Start OSD drawing on RTSP video channel
OSD.configVideo(CHANNEL, config);
OSD.begin();
}
void loop()
{
if (Serial.available() > 0) {
String input = Serial.readString();
input.trim();
if (input.startsWith(String("REG="))) {
String name = input.substring(4);
facerecog.registerFace(name);
} else if (input.startsWith(String("DEL="))) {
String name = input.substring(4);
facerecog.removeFace(name);
} else if (input.startsWith(String("RESET"))) {
facerecog.resetRegisteredFace();
} else if (input.startsWith(String("BACKUP"))) {
facerecog.backupRegisteredFace();
} else if (input.startsWith(String("RESTORE"))) {
facerecog.restoreRegisteredFace();
}
}
delay(2000);
OSD.createBitmap(CHANNEL);
OSD.update(CHANNEL);
}
// User callback function for post processing of face recognition results
void FRPostProcess(std::vector<FaceRecognitionResult> results)
{
uint16_t im_h = config.height();
uint16_t im_w = config.width();
//Serial.print("Network URL for RTSP Streaming: ");
//Serial.print("rtsp://");
//Serial.print(ip);
//Serial.print(":");
//Serial.println(rtsp_portnum);
//Serial.println(" ");
//printf("Total number of faces detected = %d\r\n", facerecog.getResultCount());
OSD.createBitmap(CHANNEL);
if (facerecog.getResultCount() > 0) {
for (int i = 0; i < facerecog.getResultCount(); i++) {
FaceRecognitionResult item = results[i];
// Result coordinates are floats ranging from 0.00 to 1.00
// Multiply with RTSP resolution to get coordinates in pixels
int xmin = (int)(item.xMin() * im_w);
int xmax = (int)(item.xMax() * im_w);
int ymin = (int)(item.yMin() * im_h);
int ymax = (int)(item.yMax() * im_h);
uint32_t osd_color;
if (String(item.name()) == String("unknown")) {
osd_color = OSD_COLOR_RED;
//Serial1.println("unknownuser");
} else {
osd_color = OSD_COLOR_GREEN;
if(Last!=String(item.name()))
{
Serial1.println(item.name());
}
}
// Draw boundary box
//printf("Face %d name %s:\t%d %d %d %d\n\r", i, item.name(), xmin, xmax, ymin, ymax);
//printf("%s",item.name());
OSD.drawRect(CHANNEL, xmin, ymin, xmax, ymax, 3, osd_color);
// Print identification text above boundary box
char text_str[40];
//snprintf(text_str, sizeof(text_str), "Face:%s", item.name());
OSD.drawText(CHANNEL, xmin, ymin - OSD.getTextHeight(CHANNEL), text_str, osd_color);
}
}
OSD.update(CHANNEL);
}
则此时,当安信可小安派BW21-CBV-Kit检测到注册人脸时,则可在热敏打印模块输出对应人脸名称,以此达到纸质出入记录的效果
