

再也不怕别人动电脑了!用Python实时监控
source link: http://mp.weixin.qq.com/s?__biz=MzIzNTg3MDQyMQ%3D%3D&%3Bmid=2247486666&%3Bidx=1&%3Bsn=f9f7a57b14a458cc97aef1162b02041e
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

作者:美图博客
https://www.meitubk.com/zatan/386.html
前言
最近突然有个奇妙的想法,就是当我对着电脑屏幕的时候,电脑会先识别屏幕上的人脸是否是本人,如果识别是本人的话需要回答电脑说的暗语,答对了才会解锁并且有三次机会。如果都没答对就会发送邮件给我,通知有人在动我的电脑并上传该人头像。
过程
环境是 win10
代码我使用的是 python3
所以在开始之前需要安装一些依赖包,请按顺序安装否者会报错
pip install cmake -i https://pypi.tuna.tsinghua.edu.cn/simple pip install dlib -i https://pypi.tuna.tsinghua.edu.cn/simple pip install face_recognition -i https://pypi.tuna.tsinghua.edu.cn/simple pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple
接下来是构建识别人脸以及对比人脸的代码
import face_recognition import cv2 import numpy as np video_capture = cv2.VideoCapture(0) my_image = face_recognition.load_image_file("my.jpg") my_face_encoding = face_recognition.face_encodings(my_image)[0] known_face_encodings = [ my_face_encoding ] known_face_names = [ "Admin" ] face_names = [] face_locations = [] face_encodings = [] process_this_frame = True while True: ret, frame = video_capture.read() small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25) rgb_small_frame = small_frame[:, :, ::-1] if process_this_frame: face_locations = face_recognition.face_locations(rgb_small_frame) face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations) face_names = [] for face_encoding in face_encodings: matches = face_recognition.compare_faces(known_face_encodings, face_encoding) name = "Unknown" face_distances = face_recognition.face_distance(known_face_encodings, face_encoding) best_match_index = np.argmin(face_distances) if matches[best_match_index]: name = known_face_names[best_match_index] face_names.append(name) process_this_frame = not process_this_frame for (top, right, bottom, left), name in zip(face_locations, face_names): top *= 4 left *= 4 right *= 4 bottom *= 4 font = cv2.FONT_HERSHEY_DUPLEX cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2) cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED) cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1) cv2.imshow('Video', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break video_capture.release() cv2.destroyAllWindows()
其中 my.jpg
需要你自己拍摄上传,运行可以发现在你脸上会出现 Admin
的框框,我去网上找了张图片类似这样子
识别功能已经完成了接下来就是语音识别和语音合成,这需要使用到百度AI来实现了,去登录百度AI的官网到控制台选择左边的语音技术,然后点击面板的创建应用按钮,来到创建应用界面

创建后会得到AppID、API Key、Secret Key记下来,然后开始写语音合成的代码。安装百度AI提供的依赖包
pip install baidu-aip -i https://pypi.tuna.tsinghua.edu.cn/simple pip install playsound -i https://pypi.tuna.tsinghua.edu.cn/simple
然后是简单的语音播放代码,运行下面代码可以听到萌妹子的声音
import sys from aip import AipSpeech from playsound import playsound APP_ID = '' API_KEY = '' SECRET_KEY = '' client = AipSpeech(APP_ID, API_KEY, SECRET_KEY) result = client.synthesis('你好吖', 'zh', 1, {'vol': 5, 'per': 4, 'spd': 5, }) if not isinstance(result, dict): with open('auido.mp3', 'wb') as file: file.write(result) filepath = eval(repr(sys.path[0]).replace('\\', '/')) + '//auido.mp3' playsound(filepath)
有了上面的代码就完成了检测是否在电脑前(人脸识别)以及电脑念出暗语(语音合成)然后我们还需要回答暗号给电脑,所以还需要完成语音识别。
import wave import pyaudio from aip import AipSpeech APP_ID = '' API_KEY = '' SECRET_KEY = '' client = AipSpeech(APP_ID, API_KEY, SECRET_KEY) CHUNK = 1024 FORMAT = pyaudio.paInt16 CHANNELS = 1 RATE = 8000 RECORD_SECONDS = 3 WAVE_OUTPUT_FILENAME = "output.wav" p = pyaudio.PyAudio() stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK) print("* recording") frames = [] for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)): data = stream.read(CHUNK) frames.append(data) print("* done recording") stream.stop_stream() stream.close() p.terminate() wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb') wf.setnchannels(CHANNELS) wf.setsampwidth(p.get_sample_size(FORMAT)) wf.setframerate(RATE) wf.writeframes(b''.join(frames)) def get_file_content(): with open(WAVE_OUTPUT_FILENAME, 'rb') as fp: return fp.read() result = client.asr(get_file_content(), 'wav', 8000, {'dev_pid': 1537, }) print(result)
运行此代码之前需要安装 pyaudio
依赖包,由于在win10系统上安装会报错所以可以通过如下方式安装。到这个链接 https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyaudio 去下载对应的安装包然后安装即可。

运行后我说了你好,可以看到识别出来了。那么我们的小模块功能就都做好了接下来就是如何去整合它们。可以发现在人脸识别代码中 if matches[best_match_index]
这句判断代码就是判断是否为电脑主人,所以我们把这个判断语句当作main函数的入口。
if matches[best_match_index]: # 在这里写识别到之后的功能 name = known_face_names[best_match_index]
那么识别到后我们应该让电脑发出询问暗号,也就是语音合成代码,然我们将它封装成一个函数,顺便重构下人脸识别的代码。
import cv2 import time import numpy as np import face_recognition video_capture = cv2.VideoCapture(0) my_image = face_recognition.load_image_file("my.jpg") my_face_encoding = face_recognition.face_encodings(my_image)[0] known_face_encodings = [ my_face_encoding ] known_face_names = [ "Admin" ] face_names = [] face_locations = [] face_encodings = [] process_this_frame = True def speak(content): import sys from aip import AipSpeech from playsound import playsound APP_ID = '' API_KEY = '' SECRET_KEY = '' client = AipSpeech(APP_ID, API_KEY, SECRET_KEY) result = client.synthesis(content, 'zh', 1, {'vol': 5, 'per': 0, 'spd': 5, }) if not isinstance(result, dict): with open('auido.mp3', 'wb') as file: file.write(result) filepath = eval(repr(sys.path[0]).replace('\\', '/')) + '//auido.mp3' playsound(filepath) try: while True: ret, frame = video_capture.read() small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25) rgb_small_frame = small_frame[:, :, ::-1] if process_this_frame: face_locations = face_recognition.face_locations(rgb_small_frame) face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations) face_names = [] for face_encoding in face_encodings: matches = face_recognition.compare_faces(known_face_encodings, face_encoding) name = "Unknown" face_distances = face_recognition.face_distance(known_face_encodings, face_encoding) best_match_index = np.argmin(face_distances) if matches[best_match_index]: speak("识别到人脸,开始询问暗号,请回答接下来我说的问题") time.sleep(1) speak("天王盖地虎") error = 1 / 0 name = known_face_names[best_match_index] face_names.append(name) process_this_frame = not process_this_frame for (top, right, bottom, left), name in zip(face_locations, face_names): top *= 4 left *= 4 right *= 4 bottom *= 4 font = cv2.FONT_HERSHEY_DUPLEX cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2) cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED) cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1) cv2.imshow('Video', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break except Exception as e: print(e) finally: video_capture.release() cv2.destroyAllWindows()
这里有一点需要注意,由于 playsound
播放音乐的时候会一直占用这个资源,所以播放下一段音乐的时候会报错,解决方法是修改 ~\Python37\Lib\site-packages
下的 playsound.py
文件,找到如下代码

在 sleep
函数下面添加 winCommand('close', alias)
这句代码,保存下就可以了。运行发现可以正常将两句话都说出来。那么说出来之后就要去监听了,我们还要打包一个函数。
def record(): import wave import json import pyaudio from aip import AipSpeech APP_ID = '' API_KEY = '' SECRET_KEY = '' client = AipSpeech(APP_ID, API_KEY, SECRET_KEY) CHUNK = 1024 FORMAT = pyaudio.paInt16 CHANNELS = 1 RATE = 8000 RECORD_SECONDS = 3 WAVE_OUTPUT_FILENAME = "output.wav" p = pyaudio.PyAudio() stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK) print("* recording") frames = [] for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)): data = stream.read(CHUNK) frames.append(data) print("* done recording") stream.stop_stream() stream.close() p.terminate() wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb') wf.setnchannels(CHANNELS) wf.setsampwidth(p.get_sample_size(FORMAT)) wf.setframerate(RATE) wf.writeframes(b''.join(frames)) def get_file_content(): with open(WAVE_OUTPUT_FILENAME, 'rb') as fp: return fp.read() result = client.asr(get_file_content(), 'wav', 8000, {'dev_pid': 1537, }) result = json.loads(str(result).replace("'", '"')) return result["result"][0]
将识别到人脸后的代码修改成如下
if matches[best_match_index]: speak("识别到人脸,开始询问暗号,请回答接下来我说的问题") time.sleep(1) speak("天王盖地虎") flag = False for times in range(0, 3): content = record() if "小鸡炖蘑菇" in content: speak("暗号通过") flag = True break else: speak("暗号不通过,再试一次") if flag: print("解锁") else: print("发送邮件并将坏人人脸图片上传!") error = 1 / 0 name = known_face_names[best_match_index]
运行看看效果,回答电脑 小鸡炖蘑菇
,电脑回答暗号通过。这样功能就基本上完成了。

结语
至于发送邮件的功能和锁屏解锁的功能我就不一一去实现了,我想这应该难不倒在座的各位吧。锁屏功能可以HOOK让键盘时间无效化,然后用窗口再覆盖整个桌面即可,至于邮箱发送网上文章很多的。
好文章,我 在看 :heart:
Recommend
-
133
民警信息二维码的背后,是中国电信智能名片提供的技术支持,该方案由一套基于区块链的三级身份认证系统,以及基于微信的名片管理工具组成,在身份防伪和数据安全方面具有业界领先的优势。
-
38
作者:三羊 来源: https://snayan.github.io/post/2019/in_depth_animation_frame/ 在前端性能优化策略中,耳熟能详的手段有,雅虎 35 条军规,使用 cache,减少请求数量,使用coo...
-
62
用了那么多年的express.js,终于有时间来深入学习express,然后顺便再和koa2的实现方式对比一下。 老实说,还没看express.js源码之前,一直觉得express.js还是很不错的,无论从api设计,还是使用上都是可以的。但是这次阅读完express代码之后,我可能改变...
-
35
2020年3月17日发布,Java正式发布了JDK 14 ,目前已经可以开放下载。在JDK 14中,共有16个新特性,本文主要来介绍其中的一个特性:JEP 358: Helpful NullPointerExceptions null何错之有? 对于Java程序员来说,null...
-
25
一、为什么需要线程池 在实际使用中,线程是很占用系统资源的,如果对线程管理不完善的话很容易导致系统问题。因此,在大多数...
-
33
看完这篇,面试再也不怕被问 Webpack 热更新 2019-09-25 发布于
-
10
上班摸鱼程序,再也不怕领导偷偷出现在身后了 发表于...
-
10
记录一下笔记,给各位小伙伴们分享一些常用的Vue3新特性及哪些方法发生了变更。 我这里只写一些常用的,更多请看Vue3官网这里
-
6
MySQL 性能优化的 9 种姿势,面试再也不怕了!1、选择最合适的字段属性Mysql是一种关系型数据库,可以很好地支持大数据量的存储,但是一般来说,数据库中的表越小,在它上面执行的查询也就越快。因此,在...
-
7
正确使用【亚马逊小卡片】,再也不怕被封号!
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK