办公室摸鱼防被抓项目

本项目一共分为三个部分:

  • esp32传输视频流至电脑
  • facenet实现视频流的人脸识别
  • 将esp32传输至电脑的视频流进行识别
  • 识别出目标人物后,电脑自动切屏

目录

一、esp32传输视频流

  1. 所需器材
  2. esp32接线图
  3. esp32开发环境配置
  4. 代码及实现效果

二、facenet实现视频流人脸识别

  1. 环境配置
  2. facenet源码获取
  3. 安装和配置facenet环境
  4. 下载LFW数据集
  5. 对LFW数据集进行预处理
  6. 下载训练好的网络模型
  7. 评估预训练模型的准确率
  8. 人脸对比
  9. 收集自己的数据集
  10. 训练分类器
  11. 视频流的人脸识别

三、将esp32传输至电脑的视频流进行识别

  1. opencv读取esp32传输的视频流
  2. 对读取的视频流进行识别

四、识别出指定人物后,电脑切屏

  1. 环境配置
  2. 代码实现

五、主要代码

  1. get_faces.py
  2. real_time_recognition.py
  3. face.py
  4. esp32_cam.py
  5. screen.py

一、esp32传输视频流 {#1}

  1. 所需器材

    器材 数量
    esp32-CAM(含摄像头) 1枚
    USB转TTL转接头 1枚
    杜邦线 若干
  2. esp32接线图

    • 运行调试模式接线图:
      办公室摸鱼防被抓项目

    • 下载模式接线图:
      办公室摸鱼防被抓项目

    • 详情请参考csdn博客

  3. 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
      办公室摸鱼防被抓项目

  4. 代码及实现效果

    • Arduino本身自带的示例中有现成的代码,我们只需要稍作修改,并不用自己来写。

    • 打开文件–>示例–>ESP32–>Camera–>CameraWebServer文件,然后对代码做以下修改:将代码中原本的摄像头定义注释掉,使用AI THINKER的摄像头定义。
      办公室摸鱼防被抓项目

    • 修改完后将指定位置改为自己的WiFi名和密码,之后将esp32设置为下载模式,开始编译并上传代码。
      办公室摸鱼防被抓项目

    • 如果代码报错,请检查是否安装WiFi库,若未安装请打开项目–>加载库–>管理库搜索WiFi并安装。

    • 代码烧录完毕后,将esp32设置为运行调试模式,按RSt键,之后打开串口管理器,将波特率设为115200,在浏览器中输入串口返回的url即可。
      办公室摸鱼防被抓项目

    • 在网页的最下端点击Start Stream即可看到视频流。
      办公室摸鱼防被抓项目

二、facenet实现视频流人脸识别 {#2}

  1. 环境配置

    • python==3.6
    • tensorflow==1.7
    • scikit-learn
    • opencv-python
    • h5py
    • matplotlib
    • Pillow
    • requests
    • psutil
    • scipy==1.2.1
    • pandas
    • numpy==1.16.1
  2. facenet源码获取

    • facenet源码可以直接去GitHub进行下载。

    • 无法登录GitHub的可以去我的百度网盘下载,提取码为6nsy

    • 解压源码后会得到如图所示文件:
      办公室摸鱼防被抓项目

  3. 安装和配置facenet环境

    • 在电脑Anconda3\Lib\site-packages目录下新建一个名为facenet的文件夹。因为这里我单独安装了一个虚拟环境,所以路径有些不一样,这个根据实际情况而定。
      办公室摸鱼防被抓项目

    • 然后,将facenet-master\src文件夹下的所有文件都复制到刚刚新建的facenet文件夹下。
      办公室摸鱼防被抓项目

    • 然后,将facenet文件夹中名为align的文件复制到site-packages文件夹下。

    • 下面开始配置环境变量,打开设置–>系统–>关于–>高级系统设置
      办公室摸鱼防被抓项目

    打开环境变量,在用户变量中新建一个名为PYTHONPATH的变量,并将之前的facenet文件夹的路径填入变量名。
    办公室摸鱼防被抓项目

    • cmd中输入set查看设置情况。
      办公室摸鱼防被抓项目

    办公室摸鱼防被抓项目

  4. 下载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的文件夹。
      办公室摸鱼防被抓项目

  5. 对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文件夹,请根据自己的实际情况填写。

      办公室摸鱼防被抓项目

    • 代码运行成功结果如下:

      办公室摸鱼防被抓项目

  6. 下载训练好的网络模型

    • 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文件夹下。
      办公室摸鱼防被抓项目

    • 其实我们也可以去训练自己的模型,但是会比较慢,所以这里我们就直接使用这些预训练模型。

  7. 评估预训练模型的准确率

    • 在Anaconda Propmt下定位到facenet-master文件夹下。

    • 输入以下命令:

      python src\validate_on_lfw.py data\lfw\lfw_160 src\models\20180408-102900
      

      这里仍然需要输入两个路径作为参数,第一个是存放处理后的数据集的lfw_160文件夹,第二个是预训练模型的路径,请根据实际情况填写。

    • 结果如图:
      办公室摸鱼防被抓项目

  8. 人脸对比

    • facenet可以直接对比两个人脸经过它的网络映射之后的欧氏距离,以此来判断这两张人脸是否为同一个人。

    • facenet-master\src文件下存放两张人脸图片。
      办公室摸鱼防被抓项目

    • 在Anaconda Propmt中定位到facenet-master\src文件夹下,输入以下命令:

      python compare.py models\20180408-102900 1.jpg 2.jpg
      

      这里需要输入三个路径作为参数,第一个是预训练模型的路径,剩下两个是两张图片的路径。

    • 运行结果如下:

      办公室摸鱼防被抓项目

    • 成功完成以上步骤后,代表我们下载的facenet源码已经调试完毕,可以进行人脸识别,接下来我们要进行视频流的人脸识别。

  9. 收集自己的数据集

    • 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
      
  10. 训练分类器

    • 有了自己的人脸数据集后,我们就可以开始训练自己的分类器了。

    • 在Anaconda Propmt中定位到facenet-master文件夹下,输入以下命令:

      python classifier.py TRAIN my_lfw models\20180408-102900 my_classifier.pkl
      

      这个命令需要四个参数:TRAIN是设置代码为训练模式、数据集路径、预训练模型路径、训练出的分类器的路径。

    • 结果如下:

      办公室摸鱼防被抓项目

      办公室摸鱼防被抓项目

  11. 视频流的人脸识别

    • 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)
      

      办公室摸鱼防被抓项目

    • 修改完毕之后,就可以正常进行人脸识别了。

三、将esp32传输至电脑的视频流进行识别 {#3}

  1. 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可以成功读取视频流。

      办公室摸鱼防被抓项目

  2. 对读取的视频流进行识别

    • 正常当我们可以成功读取视频流之后,只需直接将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()
      办公室摸鱼防被抓项目

    • 完成之后就可以正常的使用了。

四、识别出指定人物后,电脑切屏 {4}

  1. 环境配置
    • pyautogui
  2. 代码实现
    • 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 screenimport 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的快捷键进行切屏,所以有许多缺陷,大家可以去尝试更好的方法。

五、主要代码 {#5}

在最后放上主要用到的修改好的python代码。

  1. get_faces.py
    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')
    
  2. real_time_recognition.py
    # 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:]))
    
  3. face.py
    # 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
    
  4. 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
    
    if __name__ == '__main__':
       video()
    
  5. screen.py
    import pyautogui
    
    def screen():
       pyautogui.keyDown('alt')
       pyautogui.press('tab')
       pyautogui.keyUp('alt')
    
    if __name__ == '__main__':
       screen()
    
上一篇:离散数学CAI软件-2.第一个界面


下一篇:记录学习selenium中遇到的一个关于frame层的问题