前言
有时候离开电脑忘记锁屏,就会担心电脑屏幕被家长、同事偷看。如何利用20元制作笔记本电脑防偷窥神器,我打算从硬件+软件来实现,这里需要你懂亿点点单片机的知识。如果光从软件上实现并不太现实,因为需要一直打开笔记本的摄像头。
硬件
硬件 | 价格 |
---|---|
Arduino pro mini | 10 |
热释电传感器 | 7 |
Arduino pro mini是的价格在10-13元左右,人体红外传感器的价格在7-8元,硬件成本在20元。
软件
- Arduino IDE
- Pycharm
- python3
原理
当人靠近电脑时,红外传感器检测到热体靠近,发送高电平到MCU,MCU与主机电脑利用串口通信,再利用主机摄像头对热体进行人脸识别,识别为人脸,则主机关闭屏幕,达到防窥视的目的。
安装库
pip install opencv-python
pip install pyserial
pip install itchat
pip install apscheduler
pip install baidu-aip
Arduino程序
红外传感器的使用即程序,可以参考我之前的博文Arduino使用人体红外传感器,我们直接把程序烧录进Arduino上,不要忘了打开串口检测一下程序是否正常运行。
/*
*richowe
*/
int sensor_pin = 2;
int c = 0;
void setup() {
Serial.begin(9600);
pinMode(sensor_pin,INPUT);
Serial.flush();
}
void loop() {
int val = digitalRead(sensor_pin);
if (val == 1){
delay(50);
if (val == 1){
c = 1; //反转c值
Serial.println("have people");
delay(5000);
delay(5000); //延时10s
}
}
else if (c==1 && val==0){
c = 0;
Serial.println("people left"); //当人离开的时候打印
}
}
与主机的串行通信
串行通信利用的pyserial,实现方法可以参考我之前的博客Linux串口通信Arduino#2。
ctypes实现待机
利用python内置函数ctypes实现锁屏,现在给出demo程序,运行程序,成功锁屏。
from ctypes import *
def closewindows():
user32 = windll.LoadLibrary('user32.dll')
user32.LockWorkStation()
if __name__ == "__main__":
closewindows()
opencv
利用opencv打开笔记本的摄像头,实现拍照,再进行一个人脸识别或人体识别,判断热体是否为人体。如何使用opencv打开笔记本摄像头可参考我之前的博客Python opencv图像处理。
itchat
要实现远程控制,我这里想到的是之前有学习使用的网页版的itchat,使用itchat我们可以离开电脑之后实现远程监测我们的电脑前的环境。itchat的基础操作可以参考Python微信操控itchat定时发送消息。
百度AI平台
百度AI平台提供了很多接口,在这个项目上,我们可以利用到百度提供的人脸识别、人体识别的SDK。调用百度的接口可参考Python利用百度AI平台实现人脸识别。
实现方法
- 方法一
当有人靠近时,电脑屏幕直接锁定。大家要先给Arduino开发板烧录好程序,我们直接读取串口数据再利用python内置函数ctypes实现锁屏。
我们先来接收一下串口数,看一下格式是怎样的。
import serial
port = "COM4" #Arduino串口地址
rates = 9600 #设置波特率
ser = serial.Serial(port, rates, timeout=1) #设置串口
ser.flushInput() #清空缓存器
while True:
line = ser.readline()
print(line)
接收到的数据格式是b’ \r\n’ ,例如:b’have people\r\n’
接下来,就直接编写锁定程序,方法一
import serial
from ctypes import *
port = "COM4" #Arduino串口地址
rates = 9600 #设置波特率
ser = serial.Serial(port, rates, timeout=1) #设置串口
ser.flushInput() #清空缓存器
def closewindows():
while True:
line = ser.readline()
if (line == b'have people\r\n'):
user32 = windll.LoadLibrary('user32.dll')
user32.LockWorkStation()
if __name__ == "__main__":
closewindows()
运行程序,红外传感器检测到热源,电脑屏幕自动锁定,当然,记住设置密码,这样别人就不会轻易偷窥到你的电脑屏幕啦。
- 方法二
如果热源不是人的时候,是家里的小宠物的时候,那我们就可以利用opencv对热源进行拍照,再通过百度AI平台进行人脸识别,确定是热源是人的时候再将电脑屏幕关闭。
首先,我们先要调用opencv进行拍照,接着再将照片保留成jpg格式。
import cv2
def get_photo():
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) # 打开摄像头
ret, img = cap.read() # ret为返回值,img为当前帧
img1 = cv2.flip(img, 1) # 图像反转,1为左右对换
time.sleep(2) # 延迟2s
cv2.imwrite("img.jpg", img1) # 保存停止帧图
cap.release() #释放摄像头
接着,我们调用人脸识别接口,对图片是否为人像进行判断,判断为人像,屏幕锁定。当检测到不是人脸的时候,百度接口会返回这样的信息error_msg:pic not has face,当检测到正常人脸的时候,有几条信息都是可以代表是人脸,但face_token是百度唯一的人脸标识,并且为一串字符。
直接po程序
import cv2,time,serial,base64
from ctypes import *
from aip import AipFace
# 串口参数设置
port = "COM4" # Arduino串口地址
rates = 9600 # 设置波特率
ser = serial.Serial(port, rates, timeout=1) # 设置串口
ser.flushInput() # 清空缓存器
# 百度接口
APP_ID = '19492922'
API_KEY = 'nlyImVonYtURm1IcYpqvYRZn'
SECRET_KEY = 'jiMf0auF7DW2iptPElirp5n4L5esFYeC'
client = AipFace(APP_ID, API_KEY, SECRET_KEY)
def closewindows():
while True:
line = ser.readline()
if (line == b'have people\r\n'):
get_photo()
face_check()
def face_check():
with open("img.jpg", "rb") as f:
img_data = f.read()
data = base64.b64encode(img_data)
image = data.decode()
imageType = "BASE64"
client.detect(image, imageType)
options = {}
options["max_face_num"] = 10
res = client.detect(image, imageType, options)
#print(res)
if (res['error_msg'] == 'pic not has face'):
print("not has people")
elif (res['result']['face_list'][0]['face_token'] != 'NONE'):
user32 = windll.LoadLibrary('user32.dll')
user32.LockWorkStation()
def get_photo():
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) # 打开摄像头
ret, img = cap.read() # ret为返回值,img为当前帧
img1 = cv2.flip(img, 1) # 图像反转,1为左右对换
time.sleep(2)
cv2.imwrite("img.jpg", img1) # 保存停止帧图
cap.release()
if __name__ == "__main__":
closewindows()
- 方法三
利用itchat进行微信监控,当检测到热体的时候,拍照并将照片发到微信,我们可以判断是否锁屏。
直接给出程序
import itchat
import serial
import cv2
import time
from ctypes import *
from itchat.content import PICTURE, RECORDING, ATTACHMENT, VIDEO, TEXT, MAP
from apscheduler.schedulers.background import BackgroundScheduler
port = "COM4" #Arduino串口地址
rates = 9600 #设置波特率
ser = serial.Serial(port, rates, timeout=1) #设置串口
ser.flushInput() #清空缓存器
def job_function():
val = 1
while True:
line = ser.readline()
if (val == 1 and line == b'have people\r\n'):
itchat.send("有人靠近,正在获取图像...",toUserName="filehelper")
get_photo()
itchat.send_image("img.jpg", toUserName="filehelper")
val-=1
time.sleep(10)
elif (line == b'people left\r\n'):
itchat.send("已经离开...",toUserName="filehelper")
val+=1
break
@itchat.msg_register([TEXT,PICTURE])
def send_photo(msg):
if (msg.text == "拍照"):
get_photo()
itchat.send("正在拍照...",toUserName="filehelper")
itchat.send_image("img.jpg", toUserName="filehelper")
elif (msg.text == "锁屏"):
user32 = windll.LoadLibrary('user32.dll')
user32.LockWorkStation()
itchat.send("执行锁屏!", toUserName="filehelper")
def get_photo():
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) # 打开摄像头
ret, img = cap.read() # ret为返回值,img为当前帧
img1 = cv2.flip(img, 1) # 图像反转,1为左右对换
time.sleep(2)
cv2.imwrite("img.jpg", img1) # 保存停止帧图
cap.release()
scheduler = BackgroundScheduler()
scheduler.add_job(job_function, 'interval', minutes=1)
if __name__ == '__main__':
itchat.login()
scheduler.start()
itchat.run()
防拔下!!!剩下的完整程序写完后上传
转载:https://blog.csdn.net/richowe/article/details/105607589