再也不怕別人動電腦了!用Python實(shí)時監(jiān)控
作者:美圖博客
https://www.meitubk.com/zatan/386.html
前言
最近突然有個奇妙的想法,就是當(dāng)我對著電腦屏幕的時候,電腦會先識別屏幕上的人臉是否是本人,如果識別是本人的話需要回答電腦說的暗語,答對了才會解鎖并且有三次機(jī)會。如果都沒答對就會發(fā)送郵件給我,通知有人在動我的電腦并上傳該人頭像。
過程
環(huán)境是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
接下來是構(gòu)建識別人臉以及對比人臉的代碼
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)在你臉上會出現(xiàn)Admin的框框,我去網(wǎng)上找了張圖片類似這樣子
識別功能已經(jīng)完成了接下來就是語音識別和語音合成,這需要使用到百度AI來實(shí)現(xiàn)了,去登錄百度AI的官網(wǎng)到控制臺選擇左邊的語音技術(shù),然后點(diǎn)擊面板的創(chuàng)建應(yīng)用按鈕,來到創(chuàng)建應(yīng)用界面
打造電腦版人臉屏幕解鎖神器創(chuàng)建后會得到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
然后是簡單的語音播放代碼,運(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)
有了上面的代碼就完成了檢測是否在電腦前(人臉識別)以及電腦念出暗語(語音合成)然后我們還需要回答暗號給電腦,所以還需要完成語音識別。
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)上安裝會報錯所以可以通過如下方式安裝。到這個鏈接 https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyaudio 去下載對應(yīng)的安裝包然后安裝即可。
打造電腦版人臉屏幕解鎖神器運(yùn)行后我說了你好,可以看到識別出來了。那么我們的小模塊功能就都做好了接下來就是如何去整合它們??梢园l(fā)現(xiàn)在人臉識別代碼中if matches[best_match_index]這句判斷代碼就是判斷是否為電腦主人,所以我們把這個判斷語句當(dāng)作main函數(shù)的入口。
if?matches[best_match_index]:
????#?在這里寫識別到之后的功能
????name?=?known_face_names[best_match_index]
那么識別到后我們應(yīng)該讓電腦發(fā)出詢問暗號,也就是語音合成代碼,然我們將它封裝成一個函數(shù),順便重構(gòu)下人臉識別的代碼。
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()
這里有一點(diǎn)需要注意,由于playsound播放音樂的時候會一直占用這個資源,所以播放下一段音樂的時候會報錯,解決方法是修改~\Python37\Lib\site-packages下的playsound.py文件,找到如下代碼
打造電腦版人臉屏幕解鎖神器在sleep函數(shù)下面添加winCommand('close', alias)這句代碼,保存下就可以了。運(yùn)行發(fā)現(xiàn)可以正常將兩句話都說出來。那么說出來之后就要去監(jiān)聽了,我們還要打包一個函數(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]
將識別到人臉后的代碼修改成如下
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("發(fā)送郵件并將壞人人臉圖片上傳!")
????error?=?1?/?0
????name?=?known_face_names[best_match_index]
運(yùn)行看看效果,回答電腦小雞燉蘑菇,電腦回答暗號通過。這樣功能就基本上完成了。
打造電腦版人臉屏幕解鎖神器結(jié)語
至于發(fā)送郵件的功能和鎖屏解鎖的功能我就不一一去實(shí)現(xiàn)了,我想這應(yīng)該難不倒在座的各位吧。鎖屏功能可以HOOK讓鍵盤時間無效化,然后用窗口再覆蓋整個桌面即可,至于郵箱發(fā)送網(wǎng)上文章很多的。
好文章,我在看??
