再也不怕別人動(dòng)電腦了!用Python實(shí)時(shí)監(jiān)控
前言
最近突然有個(gè)奇妙的想法,就是當(dāng)我對(duì)著電腦屏幕的時(shí)候,電腦會(huì)先識(shí)別屏幕上的人臉是否是本人,如果識(shí)別是本人的話需要回答電腦說(shuō)的暗語(yǔ),答對(duì)了才會(huì)解鎖并且有三次機(jī)會(huì)。如果都沒答對(duì)就會(huì)發(fā)送郵件給我,通知有人在動(dòng)我的電腦并上傳該人頭像。
過(guò)程
環(huán)境是win10代碼我使用的是python3所以在開始之前需要安裝一些依賴包,請(qǐng)按順序安裝否者會(huì)報(bào)錯(cuò)
- 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
 
接下來(lái)是構(gòu)建識(shí)別人臉以及對(duì)比人臉的代碼
- 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需要你自己拍攝上傳,運(yùn)行可以發(fā)現(xiàn)在你臉上會(huì)出現(xiàn)Admin的框框,我去網(wǎng)上找了張圖片類似這樣子
識(shí)別功能已經(jīng)完成了接下來(lái)就是語(yǔ)音識(shí)別和語(yǔ)音合成,這需要使用到百度AI來(lái)實(shí)現(xiàn)了,去登錄百度AI的官網(wǎng)到控制臺(tái)選擇左邊的語(yǔ)音技術(shù),然后點(diǎn)擊面板的創(chuàng)建應(yīng)用按鈕,來(lái)到創(chuàng)建應(yīng)用界面
打造電腦版人臉屏幕解鎖神器
創(chuàng)建后會(huì)得到AppID、API Key、Secret Key記下來(lái),然后開始寫語(yǔ)音合成的代碼。安裝百度AI提供的依賴包
- pip install baidu-aip -i https://pypi.tuna.tsinghua.edu.cn/simple
 - pip install playsound -i https://pypi.tuna.tsinghua.edu.cn/simple
 
然后是簡(jiǎn)單的語(yǔ)音播放代碼,運(yùn)行下面代碼可以聽到萌妹子的聲音
- 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)
 
有了上面的代碼就完成了檢測(cè)是否在電腦前(人臉識(shí)別)以及電腦念出暗語(yǔ)(語(yǔ)音合成)然后我們還需要回答暗號(hào)給電腦,所以還需要完成語(yǔ)音識(shí)別。
- 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)
 
運(yùn)行此代碼之前需要安裝pyaudio依賴包,由于在win10系統(tǒng)上安裝會(huì)報(bào)錯(cuò)所以可以通過(guò)如下方式安裝。到這個(gè)鏈接 https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyaudio 去下載對(duì)應(yīng)的安裝包然后安裝即可。
打造電腦版人臉屏幕解鎖神器
運(yùn)行后我說(shuō)了你好,可以看到識(shí)別出來(lái)了。那么我們的小模塊功能就都做好了接下來(lái)就是如何去整合它們。可以發(fā)現(xiàn)在人臉識(shí)別代碼中if matches[best_match_index]這句判斷代碼就是判斷是否為電腦主人,所以我們把這個(gè)判斷語(yǔ)句當(dāng)作main函數(shù)的入口。
- if matches[best_match_index]:
 - # 在這里寫識(shí)別到之后的功能
 - name = known_face_names[best_match_index]
 
那么識(shí)別到后我們應(yīng)該讓電腦發(fā)出詢問(wèn)暗號(hào),也就是語(yǔ)音合成代碼,然我們將它封裝成一個(gè)函數(shù),順便重構(gòu)下人臉識(shí)別的代碼。
- 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("識(shí)別到人臉,開始詢問(wèn)暗號(hào),請(qǐng)回答接下來(lái)我說(shuō)的問(wèn)題")
 - 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()
 
這里有一點(diǎn)需要注意,由于playsound播放音樂的時(shí)候會(huì)一直占用這個(gè)資源,所以播放下一段音樂的時(shí)候會(huì)報(bào)錯(cuò),解決方法是修改~\Python37\Lib\site-packages下的playsound.py文件,找到如下代碼
打造電腦版人臉屏幕解鎖神器
在sleep函數(shù)下面添加winCommand('close', alias)這句代碼,保存下就可以了。運(yùn)行發(fā)現(xiàn)可以正常將兩句話都說(shuō)出來(lái)。那么說(shuō)出來(lái)之后就要去監(jiān)聽了,我們還要打包一個(gè)函數(shù)。
- 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]
 
將識(shí)別到人臉后的代碼修改成如下
- if matches[best_match_index]:
 - speak("識(shí)別到人臉,開始詢問(wèn)暗號(hào),請(qǐng)回答接下來(lái)我說(shuō)的問(wèn)題")
 - time.sleep(1)
 - speak("天王蓋地虎")
 - flag = False
 - for times in range(0, 3):
 - content = record()
 - if "小雞燉蘑菇" in content:
 - speak("暗號(hào)通過(guò)")
 - flag = True
 - break
 - else:
 - speak("暗號(hào)不通過(guò),再試一次")
 - if flag:
 - print("解鎖")
 - else:
 - print("發(fā)送郵件并將壞人人臉圖片上傳!")
 - error = 1 / 0
 - name = known_face_names[best_match_index]
 
運(yùn)行看看效果,回答電腦小雞燉蘑菇,電腦回答暗號(hào)通過(guò)。這樣功能就基本上完成了。
打造電腦版人臉屏幕解鎖神器
結(jié)語(yǔ)
至于發(fā)送郵件的功能和鎖屏解鎖的功能我就不一一去實(shí)現(xiàn)了,我想這應(yīng)該難不倒在座的各位吧。鎖屏功能可以HOOK讓鍵盤時(shí)間無(wú)效化,然后用窗口再覆蓋整個(gè)桌面即可,至于郵箱發(fā)送網(wǎng)上文章很多的。




















 
 
 









 
 
 
 