Advertisement
safwan092

Untitled

May 13th, 2023
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.54 KB | None | 0 0
  1. #include <ArduinoWebsockets.h>
  2. #include "esp_http_server.h"
  3. #include "esp_timer.h"
  4. #include "esp_camera.h"
  5. #include "camera_index.h"
  6. #include "Arduino.h"
  7. #include "fd_forward.h"
  8. #include "fr_forward.h"
  9. #include "fr_flash.h"
  10.  
  11. #define RXD2 14
  12. #define TXD2 2
  13.  
  14. const char* ssid = "network";
  15. const char* password = "123456789";
  16.  
  17. #define ENROLL_CONFIRM_TIMES 5
  18. #define FACE_ID_SAVE_NUMBER 7
  19.  
  20. // Select camera model
  21. //#define CAMERA_MODEL_WROVER_KIT
  22. //#define CAMERA_MODEL_ESP_EYE
  23. //#define CAMERA_MODEL_M5STACK_PSRAM
  24. //#define CAMERA_MODEL_M5STACK_WIDE
  25. #define CAMERA_MODEL_AI_THINKER
  26. #include "camera_pins.h"
  27.  
  28. using namespace websockets;
  29. WebsocketsServer socket_server;
  30.  
  31. camera_fb_t * fb = NULL;
  32.  
  33. long current_millis;
  34. long last_detected_millis = 0;
  35.  
  36. //#define relay_pin 2 // pin 12 can also be used
  37. unsigned long door_opened_millis = 0;
  38. long interval = 5000; // open lock for ... milliseconds
  39. bool face_recognised = false;
  40.  
  41. void app_facenet_main();
  42. void app_httpserver_init();
  43.  
  44. typedef struct
  45. {
  46. uint8_t *image;
  47. box_array_t *net_boxes;
  48. dl_matrix3d_t *face_id;
  49. } http_img_process_result;
  50.  
  51.  
  52. static inline mtmn_config_t app_mtmn_config()
  53. {
  54. mtmn_config_t mtmn_config = {0};
  55. mtmn_config.type = FAST;
  56. mtmn_config.min_face = 80;
  57. mtmn_config.pyramid = 0.707;
  58. mtmn_config.pyramid_times = 4;
  59. mtmn_config.p_threshold.score = 0.6;
  60. mtmn_config.p_threshold.nms = 0.7;
  61. mtmn_config.p_threshold.candidate_number = 20;
  62. mtmn_config.r_threshold.score = 0.7;
  63. mtmn_config.r_threshold.nms = 0.7;
  64. mtmn_config.r_threshold.candidate_number = 10;
  65. mtmn_config.o_threshold.score = 0.7;
  66. mtmn_config.o_threshold.nms = 0.7;
  67. mtmn_config.o_threshold.candidate_number = 1;
  68. return mtmn_config;
  69. }
  70. mtmn_config_t mtmn_config = app_mtmn_config();
  71.  
  72. face_id_name_list st_face_list;
  73. static dl_matrix3du_t *aligned_face = NULL;
  74.  
  75. httpd_handle_t camera_httpd = NULL;
  76.  
  77. typedef enum
  78. {
  79. START_STREAM,
  80. START_DETECT,
  81. SHOW_FACES,
  82. START_RECOGNITION,
  83. START_ENROLL,
  84. ENROLL_COMPLETE,
  85. DELETE_ALL,
  86. } en_fsm_state;
  87. en_fsm_state g_state;
  88.  
  89. typedef struct
  90. {
  91. char enroll_name[ENROLL_NAME_LEN];
  92. } httpd_resp_value;
  93.  
  94. httpd_resp_value st_name;
  95.  
  96. void setup() {
  97. Serial.begin(115200);
  98. Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
  99. Serial.setDebugOutput(true);
  100. Serial.println();
  101.  
  102. //digitalWrite(relay_pin, LOW);
  103. //pinMode(relay_pin, OUTPUT);
  104.  
  105. camera_config_t config;
  106. config.ledc_channel = LEDC_CHANNEL_0;
  107. config.ledc_timer = LEDC_TIMER_0;
  108. config.pin_d0 = Y2_GPIO_NUM;
  109. config.pin_d1 = Y3_GPIO_NUM;
  110. config.pin_d2 = Y4_GPIO_NUM;
  111. config.pin_d3 = Y5_GPIO_NUM;
  112. config.pin_d4 = Y6_GPIO_NUM;
  113. config.pin_d5 = Y7_GPIO_NUM;
  114. config.pin_d6 = Y8_GPIO_NUM;
  115. config.pin_d7 = Y9_GPIO_NUM;
  116. config.pin_xclk = XCLK_GPIO_NUM;
  117. config.pin_pclk = PCLK_GPIO_NUM;
  118. config.pin_vsync = VSYNC_GPIO_NUM;
  119. config.pin_href = HREF_GPIO_NUM;
  120. config.pin_sscb_sda = SIOD_GPIO_NUM;
  121. config.pin_sscb_scl = SIOC_GPIO_NUM;
  122. config.pin_pwdn = PWDN_GPIO_NUM;
  123. config.pin_reset = RESET_GPIO_NUM;
  124. config.xclk_freq_hz = 20000000;
  125. config.pixel_format = PIXFORMAT_JPEG;
  126. //init with high specs to pre-allocate larger buffers
  127. if (psramFound()) {
  128. config.frame_size = FRAMESIZE_UXGA;
  129. config.jpeg_quality = 10;
  130. config.fb_count = 2;
  131. } else {
  132. config.frame_size = FRAMESIZE_SVGA;
  133. config.jpeg_quality = 12;
  134. config.fb_count = 1;
  135. }
  136.  
  137. #if defined(CAMERA_MODEL_ESP_EYE)
  138. pinMode(13, INPUT_PULLUP);
  139. pinMode(14, INPUT_PULLUP);
  140. #endif
  141.  
  142. // camera init
  143. esp_err_t err = esp_camera_init(&config);
  144. if (err != ESP_OK) {
  145. Serial.printf("Camera init failed with error 0x%x", err);
  146. return;
  147. }
  148.  
  149. sensor_t * s = esp_camera_sensor_get();
  150. s->set_framesize(s, FRAMESIZE_QVGA);
  151.  
  152. #if defined(CAMERA_MODEL_M5STACK_WIDE)
  153. s->set_vflip(s, 1);
  154. s->set_hmirror(s, 1);
  155. #endif
  156.  
  157. WiFi.begin(ssid, password);
  158. WiFi.setSleep(false);
  159. while (WiFi.status() != WL_CONNECTED) {
  160. delay(500);
  161. Serial.print(".");
  162. }
  163. Serial.println("");
  164. Serial.println("WiFi connected");
  165.  
  166. app_httpserver_init();
  167. app_facenet_main();
  168. socket_server.listen(82);
  169.  
  170. Serial.print("Camera Ready! Use 'http://");
  171. Serial.print(WiFi.localIP());
  172. Serial.println("' to connect");
  173. }
  174.  
  175. static esp_err_t index_handler(httpd_req_t *req) {
  176. httpd_resp_set_type(req, "text/html");
  177. httpd_resp_set_hdr(req, "Content-Encoding", "gzip");
  178. return httpd_resp_send(req, (const char *)index_ov2640_html_gz, index_ov2640_html_gz_len);
  179. }
  180.  
  181. httpd_uri_t index_uri = {
  182. .uri = "/",
  183. .method = HTTP_GET,
  184. .handler = index_handler,
  185. .user_ctx = NULL
  186. };
  187.  
  188. void app_httpserver_init ()
  189. {
  190. httpd_config_t config = HTTPD_DEFAULT_CONFIG();
  191. if (httpd_start(&camera_httpd, &config) == ESP_OK)
  192. Serial.println("httpd_start");
  193. {
  194. httpd_register_uri_handler(camera_httpd, &index_uri);
  195. }
  196. }
  197.  
  198. void app_facenet_main()
  199. {
  200. face_id_name_init(&st_face_list, FACE_ID_SAVE_NUMBER, ENROLL_CONFIRM_TIMES);
  201. aligned_face = dl_matrix3du_alloc(1, FACE_WIDTH, FACE_HEIGHT, 3);
  202. read_face_id_from_flash_with_name(&st_face_list);
  203. }
  204.  
  205. static inline int do_enrollment(face_id_name_list *face_list, dl_matrix3d_t *new_id)
  206. {
  207. ESP_LOGD(TAG, "START ENROLLING");
  208. int left_sample_face = enroll_face_id_to_flash_with_name(face_list, new_id, st_name.enroll_name);
  209. ESP_LOGD(TAG, "Face ID %s Enrollment: Sample %d",
  210. st_name.enroll_name,
  211. ENROLL_CONFIRM_TIMES - left_sample_face);
  212. return left_sample_face;
  213. }
  214.  
  215. static esp_err_t send_face_list(WebsocketsClient &client)
  216. {
  217. client.send("delete_faces"); // tell browser to delete all faces
  218. face_id_node *head = st_face_list.head;
  219. char add_face[64];
  220. for (int i = 0; i < st_face_list.count; i++) // loop current faces
  221. {
  222. sprintf(add_face, "listface:%s", head->id_name);
  223. client.send(add_face); //send face to browser
  224. head = head->next;
  225. }
  226. }
  227.  
  228. static esp_err_t delete_all_faces(WebsocketsClient &client)
  229. {
  230. delete_face_all_in_flash_with_name(&st_face_list);
  231. client.send("delete_faces");
  232. }
  233.  
  234. void handle_message(WebsocketsClient &client, WebsocketsMessage msg)
  235. {
  236. if (msg.data() == "stream") {
  237. g_state = START_STREAM;
  238. client.send("STREAMING");
  239. }
  240. if (msg.data() == "detect") {
  241. g_state = START_DETECT;
  242. client.send("DETECTING");
  243. }
  244. if (msg.data().substring(0, 8) == "capture:") {
  245. g_state = START_ENROLL;
  246. char person[FACE_ID_SAVE_NUMBER * ENROLL_NAME_LEN] = {0,};
  247. msg.data().substring(8).toCharArray(person, sizeof(person));
  248. memcpy(st_name.enroll_name, person, strlen(person) + 1);
  249. client.send("CAPTURING");
  250. }
  251. if (msg.data() == "recognise") {
  252. g_state = START_RECOGNITION;
  253. client.send("RECOGNISING");
  254. }
  255. if (msg.data() == "openDoor") {
  256. client.send("Openning Door");
  257. open_door(client);
  258. }
  259.  
  260. if (msg.data().substring(0, 7) == "remove:") {
  261. char person[ENROLL_NAME_LEN * FACE_ID_SAVE_NUMBER];
  262. msg.data().substring(7).toCharArray(person, sizeof(person));
  263. delete_face_id_in_flash_with_name(&st_face_list, person);
  264. send_face_list(client); // reset faces in the browser
  265. }
  266. if (msg.data() == "delete_all") {
  267. delete_all_faces(client);
  268. }
  269. }
  270.  
  271. void open_door(WebsocketsClient &client) {
  272. //if (digitalRead(relay_pin) == LOW) {
  273. //digitalWrite(relay_pin, HIGH); //close (energise) relay so door unlocks
  274. //Serial.println("Door Unlocked");
  275. client.send("door_open");
  276. door_opened_millis = millis(); // time relay closed and door opened
  277. //}
  278. }
  279.  
  280. void loop() {
  281. auto client = socket_server.accept();
  282. client.onMessage(handle_message);
  283. dl_matrix3du_t *image_matrix = dl_matrix3du_alloc(1, 320, 240, 3);
  284. http_img_process_result out_res = {0};
  285. out_res.image = image_matrix->item;
  286.  
  287. send_face_list(client);
  288. client.send("STREAMING");
  289.  
  290. while (client.available()) {
  291. client.poll();
  292.  
  293. if (millis() - interval > door_opened_millis) { // current time - face recognised time > 5 secs
  294. // digitalWrite(relay_pin, LOW); //open relay
  295. }
  296.  
  297. fb = esp_camera_fb_get();
  298.  
  299. if (g_state == START_DETECT || g_state == START_ENROLL || g_state == START_RECOGNITION)
  300. {
  301. out_res.net_boxes = NULL;
  302. out_res.face_id = NULL;
  303.  
  304. fmt2rgb888(fb->buf, fb->len, fb->format, out_res.image);
  305.  
  306. out_res.net_boxes = face_detect(image_matrix, &mtmn_config);
  307.  
  308. if (out_res.net_boxes)
  309. {
  310. if (align_face(out_res.net_boxes, image_matrix, aligned_face) == ESP_OK)
  311. {
  312.  
  313. out_res.face_id = get_face_id(aligned_face);
  314. last_detected_millis = millis();
  315. if (g_state == START_DETECT) {
  316. client.send("FACE DETECTED");
  317. }
  318.  
  319. if (g_state == START_ENROLL)
  320. {
  321. int left_sample_face = do_enrollment(&st_face_list, out_res.face_id);
  322. char enrolling_message[64];
  323. sprintf(enrolling_message, "SAMPLE NUMBER %d FOR %s", ENROLL_CONFIRM_TIMES - left_sample_face, st_name.enroll_name);
  324. client.send(enrolling_message);
  325. if (left_sample_face == 0)
  326. {
  327. ESP_LOGI(TAG, "Enrolled Face ID: %s", st_face_list.tail->id_name);
  328. g_state = START_STREAM;
  329. char captured_message[64];
  330. sprintf(captured_message, "FACE CAPTURED FOR %s", st_face_list.tail->id_name);
  331. client.send(captured_message);
  332. send_face_list(client);
  333.  
  334. }
  335. }
  336.  
  337. if (g_state == START_RECOGNITION && (st_face_list.count > 0))
  338. {
  339. face_id_node *f = recognize_face_with_name(&st_face_list, out_res.face_id);
  340. if (f)
  341. {
  342. char recognised_message[64];
  343. sprintf(recognised_message, "Student # %s is present", f->id_name);
  344. open_door(client);
  345. client.send(recognised_message);
  346. Serial2.print(String(f->id_name));
  347. Serial2.print("A");
  348. Serial2.print("\n");
  349. delay(5000);
  350. }
  351. else
  352. {
  353. client.send("FACE NOT RECOGNISED");
  354. }
  355. }
  356. dl_matrix3d_free(out_res.face_id);
  357. }
  358.  
  359. }
  360. else
  361. {
  362. if (g_state != START_DETECT) {
  363. client.send("NO FACE DETECTED");
  364. }
  365. }
  366.  
  367. if (g_state == START_DETECT && millis() - last_detected_millis > 500) { // Detecting but no face detected
  368. client.send("DETECTING");
  369. }
  370.  
  371. }
  372.  
  373. client.sendBinary((const char *)fb->buf, fb->len);
  374.  
  375. esp_camera_fb_return(fb);
  376. fb = NULL;
  377. }
  378. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement