——BETCuser
In this project, we develop a paper entry and exit recorder using the BW21-CBV-Kit from Ai-Thinker and a thermal printing module. This device can recognize individuals through face detection and print out entry and exit records in real-time.
You can select a thermal printing module on your own from shopping platforms.
According to the official instructions of the thermal printing module, it can be connected using TTL, RS232, or USB modes. I chose the TTL connection mode with the BW21-CBV-Kit.
Based on the official documentation of the BW21-CBV-Kit, IOA2 and IOA3 correspond to UART1_TXD and UART1_RXD respectively.
Connect IOA2 to the RXD of the thermal printing module via a ribbon cable, and IOA3 to the TXD of the thermal printing module, to complete the basic hardware connection.
To enable the Ameba BW21-CBV-Kit to output content normally, initialize Serial1.begin(115200);. When a face is detected, use Serial1.println(item.name()); to print the name of the detected person.
Complete Code#include "WiFi.h"
#include "StreamIO.h"
#include "VideoStream.h"
#include "RTSP.h"
#include "NNFaceDetectionRecognition.h"
#include "VideoStreamOverlay.h"
#define CHANNEL 0
#define CHANNELNN 3
#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";
char pass[] = "password";
int status = WL_IDLE_STATUS;
String Last = " ";
IPAddress ip;
int rtsp_portnum;
void setup() {
Serial.begin(115200);
Serial1.begin(115200);
while (status != WL_CONNECTED) {
status = WiFi.begin(ssid, pass);
delay(2000);
}
ip = WiFi.localIP();
config.setBitrate(2 * 1024 * 1024);
Camera.configVideoChannel(CHANNEL, config);
Camera.configVideoChannel(CHANNELNN, configNN);
Camera.videoInit();
rtsp.configVideo(config);
rtsp.begin();
rtsp_portnum = rtsp.getPort();
facerecog.configVideo(configNN);
facerecog.modelSelect(FACE_RECOGNITION, NA_MODEL, DEFAULT_SCRFD, DEFAULT_MOBILEFACENET);
facerecog.begin();
facerecog.setResultCallback(FRPostProcess);
videoStreamer.registerInput(Camera.getStream(CHANNEL));
videoStreamer.registerOutput(rtsp);
if (videoStreamer.begin() != 0) {
//Serial.println("StreamIO link start failed");
}
Camera.channelBegin(CHANNEL);
videoStreamerRGBFD.registerInput(Camera.getStream(CHANNELNN));
videoStreamerRGBFD.setStackSize();
videoStreamerRGBFD.setTaskPriority();
videoStreamerRGBFD.registerOutput(facerecog);
if (videoStreamerRGBFD.begin() != 0) {
//Serial.println("StreamIO link start failed");
}
Camera.channelBegin(CHANNELNN);
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);
}
void FRPostProcess(std::vector<FaceRecognitionResult> results) {
uint16_t im_h = config.height();
uint16_t im_w = config.width();
OSD.createBitmap(CHANNEL);
if (facerecog.getResultCount() > 0) {
for (int i = 0; i < facerecog.getResultCount(); i++) {
FaceRecognitionResult item = results[i];
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;
} else {
osd_color = OSD_COLOR_GREEN;
if (Last != String(item.name())) {
Serial1.println(item.name());
Last = String(item.name());
}
}
OSD.drawRect(CHANNEL, xmin, ymin, xmax, ymax, 3, osd_color);
char text_str[40];
OSD.drawText(CHANNEL, xmin, ymin - OSD.getTextHeight(CHANNEL), text_str, osd_color);
}
}
OSD.update(CHANNEL);
}
When the BW21-CBV-Kit detects a registered face, it will output the corresponding name via the thermal printing module, achieving a paper-based entry and exit record.
Comments
Please log in or sign up to comment.