本项目一共分为三个部分:
所需器材
器材 | 数量 |
---|---|
esp32-CAM(含摄像头) | 1枚 |
USB转TTL转接头 | 1枚 |
杜邦线 | 若干 |
esp32接线图
运行调试模式接线图:
下载模式接线图:
详情请参考csdn博客。
esp32开发环境配置
打开Arduino IDE,在左上角的文件的首选项中添加附加开发板管理网址:http://arduino.esp8266.com/stable/package_esp8266com_index.json
,https://dl.espressif.com/dl/package_esp32_index.json
,https://www.jianshu.com/p/1e72a6a7cb7b
.
添加完成后,选择工具–>开发板–>开发板管理器,在搜索框中搜索ESP32并安装。
安装完成之后,点击工具–>开发板–>ESP32 Arduino,选择开发板型号为AL Thinker ESP32-CAM
。
代码及实现效果
Arduino本身自带的示例中有现成的代码,我们只需要稍作修改,并不用自己来写。
打开文件–>示例–>ESP32–>Camera–>CameraWebServer文件,然后对代码做以下修改:将代码中原本的摄像头定义注释掉,使用AI THINKER的摄像头定义。
修改完后将指定位置改为自己的WiFi名和密码,之后将esp32设置为下载模式,开始编译并上传代码。
如果代码报错,请检查是否安装WiFi库,若未安装请打开项目–>加载库–>管理库搜索WiFi并安装。
代码烧录完毕后,将esp32设置为运行调试模式,按RSt
键,之后打开串口管理器,将波特率设为115200
,在浏览器中输入串口返回的url即可。
在网页的最下端点击Start Stream
即可看到视频流。
环境配置
facenet源码获取
facenet源码可以直接去GitHub进行下载。
无法登录GitHub的可以去我的百度网盘下载,提取码为6nsy
。
解压源码后会得到如图所示文件:
安装和配置facenet环境
在电脑Anconda3\Lib\site-packages
目录下新建一个名为facenet
的文件夹。因为这里我单独安装了一个虚拟环境,所以路径有些不一样,这个根据实际情况而定。
然后,将facenet-master\src
文件夹下的所有文件都复制到刚刚新建的facenet文件夹下。
然后,将facenet文件夹中名为align
的文件复制到site-packages
文件夹下。
下面开始配置环境变量,打开设置–>系统–>关于–>高级系统设置。
打开环境变量,在用户变量中新建一个名为PYTHONPATH
的变量,并将之前的facenet
文件夹的路径填入变量名。
cmd
中输入set
查看设置情况。下载LFW数据集
LFW数据集是由美国马萨诸塞大学阿姆斯特分校计算机视觉实验室整理的人脸检测数据集,是评估人脸识别算法效果的公开测试数据集,全称为带标签的自然人脸数据库(Labeled Faces in the Wild)。
LFW数据库内每张图片命名方式为“lfw/name/name_xxxx.jpg”,这里“xxxx”是前面补零的四位图片编号。例如,前美国总统乔治•W•布什的第10张图片为“lfw/George_W_Bush/George_W_Bush_0010.jpg”。
LFW数据库 总共有 13233 张 JPEG 格式图片,属于 5749 个不同人。每张图片尺寸都是 250x250。
数据库下载地址:http://vis-www.cs.umass.edu/lfw/lfw.tgz
百度云地址,提取码rzm5
。
下载完数据集后在facenet-master\data
文件夹下新建一个名为lfw
的文件夹,将数据集解压进lfw
文件夹下,并在lfw
文件夹下再新建一个名为lfw_160
的文件夹。
对LFW数据集进行预处理
LFW数据集中所有图片的大小均为250*250
,我们需要将所有的数据集处理成预训练模型所使用的160*160
的大小并保存到lfw_160
文件夹下。
打开Anconda Prompt
定位到facenet-master
文件夹下,输入如下命令进行校准:
python src\align\align_dataset_mtcnn.py --help
再输入如下命令:
python src\align\align_dataset_mtcnn.py data/lfw/lfw data/lfw/lfw_160 --image_size 160 --margin 32 --random_order --gpu_memory_fraction 0.25
这个命令中需要两个相对路径作为参数,第一个路径为原数据集的lfw
文件夹,第二个路径为保存处理后的数据集的lfw_160
文件夹,请根据自己的实际情况填写。
代码运行成功结果如下:
下载训练好的网络模型
facenet提供了两个预训练模型,分别是基于CASIA-WebFace和MS-Celeb-1M人脸库训练的,如下:
Model name | LFW accuracy | Training dataset | Architecture |
---|---|---|---|
20180408-102900 | 0.9905 | CASIA-WebFace | Inception ResNet v1 |
20180402-114759 | 0.9965 | VGGFace2 | Inception ResNet v1 |
谷歌云盘的下载速度很慢,这里有百度云的地址:
模型 | 提取码 |
---|---|
20180408-102900 | o6m0 |
20180402-114759 | lu9c |
这两个模型任选其一即可,我用的是基于数据集CASIA-WebFace采用Inception ResNet v1神经网络结构训练好的模型。
模型下载完之后,将其解压至facenet-master\src\models
文件夹下。
其实我们也可以去训练自己的模型,但是会比较慢,所以这里我们就直接使用这些预训练模型。
评估预训练模型的准确率
在Anaconda Propmt下定位到facenet-master文件夹下。
输入以下命令:
python src\validate_on_lfw.py data\lfw\lfw_160 src\models\20180408-102900
这里仍然需要输入两个路径作为参数,第一个是存放处理后的数据集的lfw_160
文件夹,第二个是预训练模型的路径,请根据实际情况填写。
结果如图:
人脸对比
facenet可以直接对比两个人脸经过它的网络映射之后的欧氏距离,以此来判断这两张人脸是否为同一个人。
在facenet-master\src
文件下存放两张人脸图片。
在Anaconda Propmt中定位到facenet-master\src
文件夹下,输入以下命令:
python compare.py models\20180408-102900 1.jpg 2.jpg
这里需要输入三个路径作为参数,第一个是预训练模型的路径,剩下两个是两张图片的路径。
运行结果如下:
成功完成以上步骤后,代表我们下载的facenet源码已经调试完毕,可以进行人脸识别,接下来我们要进行视频流的人脸识别。
收集自己的数据集
在facenet-master\src
文件夹下新建一个名为my_lfw
的文件夹,用来存放我们的数据集。再新建一个名为my_lfw_160
的文件夹用来存放处理后的数据集。
然后再my_lfw
文件夹下新建几个文件夹,文件夹的名字就是你收集的人脸的名字,文件夹的数量根据人数而定。
收集人脸的代码有很多,我从csdn上随便找了一个:
import cv2 def CatchPICFromVideo(window_name, camera_idx, catch_pic_num, path_name): cv2.namedWindow(window_name) # 视频来源,可以来自一段已存好的视频,也可以直接来自USB摄像头 cap = cv2.VideoCapture(camera_idx) # 告诉OpenCV使用人脸识别分类器 data_path = "C:\ProgramData\Anaconda3\pkgs\libopencv-3.4.2-h20b85fd_0\Library\etc\haarcascades\haarcascade_frontalface_default.xml" classfier = cv2.CascadeClassifier(data_path) # 识别出人脸后要画的边框的颜色,RGB格式 color = (0, 255, 0) num = 0 while cap.isOpened(): ok, frame = cap.read() # 读取一帧数据 if not ok: break grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 将当前桢图像转换成灰度图像 # 人脸检测,1.2和2分别为图片缩放比例和需要检测的有效点数 faceRects = classfier.detectMultiScale(grey, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32)) if len(faceRects) > 0: # 大于0则检测到人脸 for faceRect in faceRects: # 单独框出每一张人脸 x, y, w, h = faceRect # 将当前帧保存为图片 img_name = '%s/%d.jpg ' %(path_name, num) image = frame[y - 10: y + h + 10, x - 10: x + w + 10] cv2.imwrite(img_name, image) num += 1 if num > catch_pic_num: # 如果超过指定最大保存数量退出循环 break # 画出矩形框 cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, 2) # 显示当前捕捉到了多少人脸图片了,这样站在那里被拍摄时心里有个数,不用两眼一抹黑傻等着 font = cv2.FONT_HERSHEY_SIMPLEX cv2.putText(frame ,'num:%d' % (num) ,(x + 30, y + 30), font, 1, (255 ,0 ,255) ,4) # 超过指定最大保存数量结束程序 if num > catch_pic_num: break # 显示图像 cv2.imshow(window_name, frame) c = cv2.waitKey(10) if c & 0xFF == ord('q'): break # 释放摄像头并销毁所有窗口 cap.release() cv2.destroyAllWindows() CatchPICFromVideo('1', 0, 100, 'D://VS Code/my_facenet/my_faces/CJL')
这段代码中的函数一共有四个参数,分别为:窗口名称、摄像头编号或视频路径、图片数量、图片储存路径。
然后我们要将这些数据集同样处理成160*160
的大小。
在Anaconda Propmt中定位到facenet-master\src
文件夹下,输入以下命令:
python align\align_dataset_mtcnn.py my_lfw my_lfw_160 --image_size 160 --margin 32 --random_order --gpu_memory_fraction 0.25
训练分类器
有了自己的人脸数据集后,我们就可以开始训练自己的分类器了。
在Anaconda Propmt中定位到facenet-master
文件夹下,输入以下命令:
python classifier.py TRAIN my_lfw models\20180408-102900 my_classifier.pkl
这个命令需要四个参数:TRAIN
是设置代码为训练模式、数据集路径、预训练模型路径、训练出的分类器的路径。
结果如下:
视频流的人脸识别
facenet的源码中有视频流人脸识别的demo,就是facenet-master\contributed\real_time_recognition.py
,我们直接拿来使用就好。
但是我们要对这个demo进行一些修改。
首先打开facenet-master\contributed\face.py
,将下图中预训练模型和分类器的路径都换成自己的路径,如果相对路径不好用,就用绝对路径。
经过这样的修改后,运行real_time_recognition.py
就可以进行人脸识别了,但是这个demo有一个缺点,那就是当遇到数据集中没有的人时,仍然会给他标注数据集中的人的名字,不会标注Other。而且我们需要根据实际情况对识别的准确度进行调整,所以我们仍需修改代码。
打开face.py
,对其进行如下修改:
修改前:
修改后:
其中,标注出来的数值根据实际情况自行决定其大小。
修改后该部分的代码:
class Identifier: def __init__(self): with open(classifier_model, 'rb') as infile: self.model, self.class_names = pickle.load(infile) def identify(self, face): if face.embedding is not None: predictions = self.model.predict_proba([face.embedding]) i = 0 while i < len(predictions[0]): if predictions[0][i] > 0.6: break i += 1 else: return None print(predictions) best_class_indices = np.argmax(predictions, axis=1) print(best_class_indices[0]) return self.class_names[best_class_indices[0]]
然后打开real_time_recognition.py
,在图中位置添加如下代码:
else: cv2.putText(frame, 'Others', (face_bb[0], face_bb[3]), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), thickness=2, lineType=2)
修改完毕之后,就可以正常进行人脸识别了。
opencv读取esp32传输的视频流
esp32传输至电脑的视频流时传输在一个网页上的,但是我们进行人脸识别时需要将视频流读取至python,这就需要用到opencv中的VideoCapture()
函数。
一般情况下我们使用VideoCapture()
只需要从摄像头编号和视频路径两个参数中任选一个,其实VideoCapture()
还可以将视频流的url作为参数来读取视频流。
首先我们要获取esp32传输的视频流的url,在esp32生成的网页中,在视频流处于播放的状态下,右击视频的播放窗口,选择复制图片地址,此时得到的就是视频流的url。
在获取视频的url之后,我们首先尝试一下opencv能否成功读取视频流。新建一个python文件,输入以下代码:
import cv2 cv2.namedWindow('esp32') cap = cv2.VideoCapture('http://192.168.137.81:81/stream') while cap.isOpened(): ok, frame = cap.read() if not ok: break cv2.imshow('esp32', frame) c = cv2.waitKey(10) if c & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
这里只需要将VideoCapture()
函数中的参数改成自己的url即可。
运行代码的时候需要将网页上的视频流暂停或者关闭网页,否则将无法读取视频流。
视频流可以成功播放之后,则opencv可以成功读取视频流。
对读取的视频流进行识别
正常当我们可以成功读取视频流之后,只需直接将real_time_recognition.py
中的VideoCapture(0)
修改为VideoCapture(url)
即可。但是由于esp32的摄像头视频的编码格式与facenet可以处理的视频流编码格式不同,直接这样做程序在读取第一帧图片后会直接报错,导致程序直接停止运行,所以我们要解决这个问题。
最好的解决方法时修改视频流的编码格式,但是我并没有找到有关这方面的很好的解决办法,所以我使用了一种很笨的方法:既然程序只能读取视频流的第一帧图片,那么我们就在读取完第一正图片后,用release()
释放视频流,然后再通过VideoCapture()
读取视频流,在读取完一帧图片后再次释放视频流,以此循环,同样可以得到完整的视频流。这样虽然会导致帧率下降,但是并不影响正常的使用。
在facenet-master\contributed
文件夹下新建一个python文件,取名为esp32_cam.py
,在里面输入以下代码:
import cv2 def video(): cap = cv2.VideoCapture("http://192.168.137.81:81/stream") #拉取视频流 while cap.isOpened(): ok, frame = cap.read() #读取一帧 if not ok: break break cap.release() #释放视频流 return frame #返回读取的一帧图片
打开real_time_recognition.py
,首先在代码开始添加import esp32_cam
,然后注释代码的以下几行:
之后在图中的位置添加frame = esp32_cam.video()
。
完成之后就可以正常的使用了。
在facenet-master\contributed
文件夹下新建一个名为screen.py
的python文件,输入以下代码:
import pyautogui def screen(): pyautogui.keyDown('alt') #按下alt键 pyautogui.press('tab') #按以下tab键 pyautogui.keyUp('alt') #松开alt键 if __name__ == '__main__': screen()
打开real_time_recognition.py
,在代码开头加上import screen
、import pyautogui
,然后再图示位置添加my_name = []
。
再在图示位置添加以下代码:
my_face = [] for i in faces: my_face.append(i.name) if ('XR' in my_face) and ('XR' not in my_name): #当指定人脸出现后,进行一次切屏 screen.screen() if ('XR' not in my_face) and ('XR' in my_name): #当指定人脸消失后,进行一次切屏 screen.screen() my_name = my_face
这样这个项目就算完成了,因为这里我用的是alt + tab
的快捷键进行切屏,所以有许多缺陷,大家可以去尝试更好的方法。
在最后放上主要用到的修改好的python代码。
import cv2 def CatchPICFromVideo(window_name, camera_idx, catch_pic_num, path_name): cv2.namedWindow(window_name) # 视频来源,可以来自一段已存好的视频,也可以直接来自USB摄像头 cap = cv2.VideoCapture(camera_idx) # 告诉OpenCV使用人脸识别分类器 data_path = "C:\ProgramData\Anaconda3\pkgs\libopencv-3.4.2-h20b85fd_0\Library\etc\haarcascades\haarcascade_frontalface_default.xml" classfier = cv2.CascadeClassifier(data_path) # 识别出人脸后要画的边框的颜色,RGB格式 color = (0, 255, 0) num = 0 while cap.isOpened(): ok, frame = cap.read() # 读取一帧数据 if not ok: break grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 将当前桢图像转换成灰度图像 # 人脸检测,1.2和2分别为图片缩放比例和需要检测的有效点数 faceRects = classfier.detectMultiScale(grey, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32)) if len(faceRects) > 0: # 大于0则检测到人脸 for faceRect in faceRects: # 单独框出每一张人脸 x, y, w, h = faceRect # 将当前帧保存为图片 img_name = '%s/%d.jpg ' %(path_name, num) image = frame[y - 10: y + h + 10, x - 10: x + w + 10] cv2.imwrite(img_name, image) num += 1 if num > catch_pic_num: # 如果超过指定最大保存数量退出循环 break # 画出矩形框 cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, 2) # 显示当前捕捉到了多少人脸图片了,这样站在那里被拍摄时心里有个数,不用两眼一抹黑傻等着 font = cv2.FONT_HERSHEY_SIMPLEX cv2.putText(frame ,'num:%d' % (num) ,(x + 30, y + 30), font, 1, (255 ,0 ,255) ,4) # 超过指定最大保存数量结束程序 if num > catch_pic_num: break # 显示图像 cv2.imshow(window_name, frame) c = cv2.waitKey(10) if c & 0xFF == ord('q'): break # 释放摄像头并销毁所有窗口 cap.release() cv2.destroyAllWindows() CatchPICFromVideo('1', 0, 100, 'D://VS Code/my_facenet/my_faces/CJL')
# coding=utf-8 """Performs face detection in realtime. Based on code from https://github.com/shanren7/real_time_face_recognition """ # MIT License # # Copyright (c) 2017 François Gervais # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. import argparse import sys import time from tkinter.constants import NO import cv2 import face import time import pyautogui import esp32_cam import screen def add_overlays(frame, faces, frame_rate): if faces is not None: for face in faces: face_bb = face.bounding_box.astype(int) cv2.rectangle(frame, (face_bb[0], face_bb[1]), (face_bb[2], face_bb[3]), (0, 255, 0), 2) if face.name is not None: cv2.putText(frame, face.name, (face_bb[0], face_bb[3]), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), thickness=2, lineType=2) else: cv2.putText(frame, 'Others', (face_bb[0], face_bb[3]), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), thickness=2, lineType=2) cv2.putText(frame, str(frame_rate) + " fps", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), thickness=2, lineType=2) def main(args): my_name = [] frame_interval = 3 # Number of frames after which to run face detection fps_display_interval = 5 # seconds frame_rate = 0 frame_count = 0 #video_capture = cv2.VideoCapture("http://192.168.137.81:81/stream") face_recognition = face.Recognition() start_time = time.time() if args.debug: print("Debug enabled") face.debug = True while True: # Capture frame-by-frame my_face = [] frame = esp32_cam.video() if (frame_count % frame_interval) == 0: faces = face_recognition.identify(frame) # Check our current fps end_time = time.time() if (end_time - start_time) > fps_display_interval: frame_rate = int(frame_count / (end_time - start_time)) start_time = time.time() frame_count = 0 add_overlays(frame, faces, frame_rate) frame_count += 1 cv2.imshow('Video', frame) my_face = [] for i in faces: my_face.append(i.name) if ('XR' in my_face) and ('XR' not in my_name): screen.screen() if ('XR' not in my_face) and ('XR' in my_name): screen.screen() my_name = my_face if cv2.waitKey(1) & 0xFF == ord('q'): break # When everything is done, release the capture #video_capture.release() cv2.destroyAllWindows() def parse_arguments(argv): parser = argparse.ArgumentParser() parser.add_argument('--debug', action='store_true', help='Enable some debug outputs.') return parser.parse_args(argv) if __name__ == '__main__': main(parse_arguments(sys.argv[1:]))
# coding=utf-8 """Face Detection and Recognition""" # MIT License # # Copyright (c) 2017 François Gervais # # This is the work of David Sandberg and shanren7 remodelled into a # high level container. It's an attempt to simplify the use of such # technology and provide an easy to use facial recognition package. # # https://github.com/davidsandberg/facenet # https://github.com/shanren7/real_time_face_recognition # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. import pickle import os import cv2 import numpy as np import tensorflow as tf from scipy import misc import align.detect_face import facenet gpu_memory_fraction = 0.3 facenet_model_checkpoint = "d://VS Code/facenet-master/src/models/20180408-102900" classifier_model = "d://VS Code/my_facenet/my_classifier_2.pkl" debug = False class Face: def __init__(self): self.name = None self.bounding_box = None self.image = None self.container_image = None self.embedding = None class Recognition: def __init__(self): self.detect = Detection() self.encoder = Encoder() self.identifier = Identifier() def add_identity(self, image, person_name): faces = self.detect.find_faces(image) if len(faces) == 1: face = faces[0] face.name = person_name face.embedding = self.encoder.generate_embedding(face) print(face.embedding) return faces def identify(self, image): faces = self.detect.find_faces(image) for i, face in enumerate(faces): if debug: cv2.imshow("Face: " + str(i), face.image) face.embedding = self.encoder.generate_embedding(face) face.name = self.identifier.identify(face) return faces class Identifier: def __init__(self): with open(classifier_model, 'rb') as infile: self.model, self.class_names = pickle.load(infile) def identify(self, face): if face.embedding is not None: predictions = self.model.predict_proba([face.embedding]) i = 0 while i < len(predictions[0]): if predictions[0][i] > 0.6: break i += 1 else: return None print(predictions) best_class_indices = np.argmax(predictions, axis=1) print(best_class_indices[0]) return self.class_names[best_class_indices[0]] class Encoder: def __init__(self): self.sess = tf.Session() with self.sess.as_default(): facenet.load_model(facenet_model_checkpoint) def generate_embedding(self, face): # Get input and output tensors images_placeholder = tf.get_default_graph().get_tensor_by_name("input:0") embeddings = tf.get_default_graph().get_tensor_by_name("embeddings:0") phase_train_placeholder = tf.get_default_graph().get_tensor_by_name("phase_train:0") prewhiten_face = facenet.prewhiten(face.image) # Run forward pass to calculate embeddings feed_dict = {images_placeholder: [prewhiten_face], phase_train_placeholder: False} return self.sess.run(embeddings, feed_dict=feed_dict)[0] class Detection: # face detection parameters minsize = 20 # minimum size of face threshold = [0.6, 0.7, 0.7] # three steps's threshold factor = 0.709 # scale factor def __init__(self, face_crop_size=160, face_crop_margin=32): self.pnet, self.rnet, self.onet = self._setup_mtcnn() self.face_crop_size = face_crop_size self.face_crop_margin = face_crop_margin def _setup_mtcnn(self): with tf.Graph().as_default(): gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=gpu_memory_fraction) sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False)) with sess.as_default(): return align.detect_face.create_mtcnn(sess, None) def find_faces(self, image): faces = [] bounding_boxes, _ = align.detect_face.detect_face(image, self.minsize, self.pnet, self.rnet, self.onet, self.threshold, self.factor) for bb in bounding_boxes: face = Face() face.container_image = image face.bounding_box = np.zeros(4, dtype=np.int32) img_size = np.asarray(image.shape)[0:2] face.bounding_box[0] = np.maximum(bb[0] - self.face_crop_margin / 2, 0) face.bounding_box[1] = np.maximum(bb[1] - self.face_crop_margin / 2, 0) face.bounding_box[2] = np.minimum(bb[2] + self.face_crop_margin / 2, img_size[1]) face.bounding_box[3] = np.minimum(bb[3] + self.face_crop_margin / 2, img_size[0]) cropped = image[face.bounding_box[1]:face.bounding_box[3], face.bounding_box[0]:face.bounding_box[2], :] face.image = misc.imresize(cropped, (self.face_crop_size, self.face_crop_size), interp='bilinear') faces.append(face) return faces
import cv2 def video(): cap = cv2.VideoCapture("http://192.168.137.81:81/stream") while cap.isOpened(): ok, frame = cap.read() if not ok: break break cap.release() return frame if __name__ == '__main__': video()
import pyautogui def screen(): pyautogui.keyDown('alt') pyautogui.press('tab') pyautogui.keyUp('alt') if __name__ == '__main__': screen()