引言

总体实现的流程:ESP32cam作为客户端,pc作为服务端通过mqtt协议建立通信,将采集的图像在电脑端显示人脸识别的方法使用的是opencv,并通过mqtt传输指令给esp32cam控制舵机云台转动。

客户端程序

#include <WebServer.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <esp32cam.h> const char* WIFI_SSID = "wifi的名称";
const char* WIFI_PASS = "wifi的密码"; WebServer server(80); static auto loRes = esp32cam::Resolution::find(320, 240);
static auto hiRes = esp32cam::Resolution::find(800, 600); void callback(char* topic, byte* payload, unsigned int length) ; bool stopEngine = true; //初始化mqtt类对象
WiFiClient espClient;
PubSubClient mqtt_client(espClient); const char* mqttServer = "broker.emqx.io";
const int mqttPort = 1883;
const char* mqttUser = "";
const char* mqttPassword = ""; int servo_y = 8;
int servo_z = 9;
int servo_y_pin = 14;
int servo_z_pin = 13;
int pos_z = 90 , pos_y = 90; void serveJpg()
{
auto frame = esp32cam::capture();
if (frame == nullptr) {
Serial.println("CAPTURE FAIL");
server.send(503, "", "");
return;
}
//Serial.printf("CAPTURE OK %dx%d %db\n", frame->getWidth(), frame->getHeight(),
//static_cast<int>(frame->size())); server.setContentLength(frame->size());
server.send(200, "image/jpeg");
WiFiClient client = server.client();
frame->writeTo(client);
} void handleJpgHi()
{
if (!esp32cam::Camera.changeResolution(hiRes)) {
Serial.println("SET-HI-RES FAIL");
}
serveJpg();
} int calculatePWM( int degree)
{
const float deadZone = 6.4;
const float max = 32;
if (degree < 0)
degree = 0;
if (degree > 180)
degree = 180;
return ( int)(((max - deadZone) / 180) * degree + deadZone);
} void mqtt_connet(){
mqtt_client.setServer(mqttServer,mqttPort);
mqtt_client.setCallback(callback);
while (!mqtt_client.connected()) {
Serial.println("Connecting to MQTT..."); if (mqtt_client.connect(mqttServer, mqttUser, mqttPassword )) { Serial.println("connected"); } else { Serial.print("failed with state ");
Serial.print(mqtt_client.state());
delay(2000);
}
}
mqtt_client.subscribe("POSITION");
}
void callback(char* topic, byte* payload, unsigned int length) {
String payloadStr = "";
for (int i=0; i<length; i++) {
payloadStr += (char)payload[i];
}
Serial.println(payloadStr); if(payloadStr.equals("RIGHT")){
pos_z --; }else if(payloadStr.equals("LEFT")){
pos_z ++;
} if(payloadStr.equals("UP")){
pos_y --; }else if(payloadStr.equals("DOWN")){
pos_y ++;
} if(pos_z >= 180) pos_z = 180;
if(pos_z <= 0) pos_z = 0;
if(pos_y >= 180) pos_y = 180;
if(pos_y <= 0) pos_y = 0;
Serial.printf("pos_z: %d pos_y: %d \n",pos_z,pos_y);
ledcWrite(servo_z,calculatePWM(pos_z));
ledcWrite(servo_y,calculatePWM(pos_y));
} void setup()
{
Serial.begin(115200);
ledcSetup(servo_y, 50, 8);
ledcSetup(servo_z, 50, 8);
ledcAttachPin(servo_y_pin, servo_y);
ledcAttachPin(servo_z_pin, servo_z); {
using namespace esp32cam;
Config cfg;
cfg.setPins(pins::AiThinker);
cfg.setResolution(hiRes);
cfg.setBufferCount(2);
cfg.setJpeg(80); bool ok = Camera.begin(cfg);
Serial.println(ok ? "CAMERA OK" : "CAMERA FAIL");
} WiFi.persistent(false);
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
} Serial.print("http://");
Serial.println(WiFi.localIP());
Serial.println(" /cam-hi.jpg");
server.on("/cam-hi.jpg", handleJpgHi);
mqtt_connet();
server.begin();
} void loop()
{
server.handleClient();
mqtt_client.loop(); }

服务端程序

import cv2
import time
import urllib.request
import numpy as np
import paho.mqtt.client as mqtt url='http://192.168.0.106/cam-hi.jpg'
cv2.namedWindow("Berhasil", cv2.WINDOW_AUTOSIZE)
face=cv2.CascadeClassifier('haarcascade_frontalface_default.xml') mqttBroker = "broker.emqx.io"
client = mqtt.Client("Cleaning-Robot",clean_session=True,userdata=None)
client.connect(mqttBroker,1883) while True:
imgresponse=urllib.request.urlopen(url)
start = time.time()
imgnp=np.array(bytearray(imgresponse.read()),dtype=np.uint8)
img=cv2.imdecode(imgnp,-1)
rows , cols , _ = img.shape
conter_x = (int)(rows / 2)
conter_y = (int)(cols / 2)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
faces = face.detectMultiScale(gray,1.3,5) for (x,y,w,h) in faces:
faces_conter_x = (int)(x + (w / 2))
faces_conter_y = (int)(y + (h / 2))
cv2.rectangle(img,(x,y), (x+w,y+h), (0,255,120),2)
cv2.putText(img,"face",(w+x,y+h),cv2.FONT_HERSHEY_PLAIN,2,(0,255,255),2) if(faces_conter_x > conter_x):
client.publish("POSITION","RIGHT")
str_x = str(conter_x - faces_conter_x)
print("RIGHT" + str_x) elif(faces_conter_x < conter_x):
client.publish("POSITION","LEFT")
str_x = str(faces_conter_y - conter_y)
print("LEFT:" + str_x) if(faces_conter_y > conter_y):
client.publish("POSITION","DOWN")
str_y = str(conter_y - faces_conter_y)
print("DOWN:" + str_y) elif(faces_conter_y < conter_y):
client.publish("POSITION","UP")
str_y = str(faces_conter_y - conter_y)
print("UP:" + str_y) end = time.time()
seconds = end - start # 处理一帧所用的时间
fps = 1 / seconds # 一秒钟可以处理多少帧
fps = "%.2f fps"%fps
cv2.putText(img, fps, (5,50 ), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 1) cv2.imshow("Berhasil",img)
key=cv2.waitKey(30) & 0xff
if key==27:
break cv2.destroyAllWindows

总结:舵机控制不稳定,可采用好的控制算法解决。

ESP32CAM 人脸识别追踪的更多相关文章

  1. 基于虹软人脸识别,实现RTMP直播推流追踪视频中所有人脸信息(C#)

    前言 大家应该都知道几个很常见的例子,比如在张学友的演唱会,在安检通道检票时,通过人像识别系统成功识别捉了好多在逃人员,被称为逃犯克星:人行横道不遵守交通规则闯红灯的路人被人脸识别系统抓拍放在大屏上以 ...

  2. 从零玩转人脸识别之RGB人脸活体检测

    从零玩转RGB人脸活体检测 前言 本期教程人脸识别第三方平台为虹软科技,本文章讲解的是人脸识别RGB活体追踪技术,免费的功能很多可以自行搭配,希望在你看完本章课程有所收获. ArcFace 离线SDK ...

  3. 虹软人脸识别 - Android Camera实时人脸追踪画框适配

    在使用虹软人脸识别Android SDK的过程中 ,预览时一般都需要绘制人脸框,但是和PC平台相机应用不同,在Android平台相机进行应用开发还需要考虑前后置相机切换.设备横竖屏切换等情况,因此在人 ...

  4. opencv 人脸识别

      背景知识 OpenCV 是一个开源的计算机视觉和机器学习库.它包含成千上万优化过的算法,为各种计算机视觉应用提供了一个通用工具包.根据这个项目的关于页面,OpenCV 已被广泛运用在各种项目上,从 ...

  5. 手 Q 人脸识别动画实现详解

    欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 前言 开门见山,先来看下效果吧. 看到这么酷炫的效果图,不得不赞叹一下我们的设计师.然而,站在程序员的角度上看,除了酷炫之外更多的是复杂.但是 ...

  6. 使用dlib中的深度残差网络(ResNet)实现实时人脸识别

    opencv中提供的基于haar特征级联进行人脸检测的方法效果非常不好,本文使用dlib中提供的人脸检测方法(使用HOG特征或卷积神经网方法),并使用提供的深度残差网络(ResNet)实现实时人脸识别 ...

  7. Android打开相机进行人脸识别,使用虹软人脸识别引擎

    上一张效果图,渣画质,能看就好 功能说明: 人脸识别使用的是虹软的FreeSDK,包含人脸追踪,人脸检测,人脸识别,年龄.性别检测功能,其中本demo只使用了FT和FR(人脸追踪和人脸识别),封装了开 ...

  8. Android 关于虹软人脸识别SDK引擎使用总结

    虹软 最近开放了人脸识别的SDK引擎(免费的哦),刚好有Android版的,就体验了一波.下面来说说Android版的SDK使用心得: ArcFace 虹软人脸认知引擎简介 目前开放的版本有人脸比对( ...

  9. Python的开源人脸识别库:离线识别率高达99.38%

    Python的开源人脸识别库:离线识别率高达99.38%   github源码:https://github.com/ageitgey/face_recognition#face-recognitio ...

随机推荐

  1. 42. Trapping Rain Water [dp][stack]

    description: Given n non-negative integers representing an elevation map where the width of each bar ...

  2. HCNA Routing&Switching之RIP防环机制

    前文我们了解了RIP的基础概念.RIP的特点.RIP报文格式.RIP度量以及RIP配置认证等相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/150085 ...

  3. Spring Cloud中的注解

    一.Eureka @EnableEurekaServer: @EnableDiscoverClient:标注服务是一个Eureka的客户端 @LoadBalanced:自动构造LoadBalancer ...

  4. Docker原理:Cgroup

    目录 Cgroup 主要功能 术语 参考 Cgroup 全称Linux Control Group, 是Linux内核的一个功能,用来限制.控制与分离一个进程组群的资源(如CPU.内存.磁盘输入输出等 ...

  5. java编译通过,运行却提示找不到或无法加载主类

    问题: HelloWorld.java 1 package myP101; 2 3 public class HelloWorld { 4 public static void main(String ...

  6. 【动画消消乐】HTML+CSS 自定义加载动画 062

    效果展示 Demo代码 HTML <!DOCTYPE html> <html lang="en"> <head> <meta charse ...

  7. File类与常用IO流第七章——Properties集合

    Properties概述 java.util.Properties extends Hashtable<k,v> implements Map<k,v> Properties类 ...

  8. Javascript闭包解析----------------v客学院技术分享

    跟java,php等编程语言一样,javascript也采用词法作用域,简单的来说就是函数的执行依赖于变量的作用域,这个作用域是在函数定义时决定的,而不是函数调用时决定的.为了实现这种词法作用域,还必 ...

  9. 理解并掌握Promise的用法

    前沿:  Promise在处理异步操作非常有用.项目中,与后端进行数据请求的时候经常要用到Promise.我们可以用promise + xhr进行ajax的封装.也可以使用基于promise封装的请求 ...

  10. 一行代码让matplotlib图表变高大上

    1 简介 matplotlib作为Python生态中最流行的数据可视化框架,虽然功能非常强大,但默认样式比较简陋,想要制作具有简洁商务风格的图表往往需要编写众多的代码来调整各种参数. 而今天要为大家介 ...