学习前言
想要实时监测电脑屏幕与摄像头前的人,我们必须满足以下几个条件:一、我们需要获取当前屏幕的分辨率,以方便之后调整电脑屏幕截图的尺寸。二、我们需要间隔的获取(while True)此时界面的截图和摄像头捕捉到的一帧图像。三、我们需要将我们获得的截图发送到我们的邮箱。
效果图
屏幕截屏:
屏幕前的人:
各个功能代码详解:
a.获取当前屏幕截图
def grab_screen(region=None):
hwin = win32gui.GetDesktopWindow()
if region:
left, top, x2, y2 = region
width = x2 - left + 1
height = y2 - top + 1
else:
width = win32api.GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN)
height = win32api.GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN)
left = win32api.GetSystemMetrics(win32con.SM_XVIRTUALSCREEN)
top = win32api.GetSystemMetrics(win32con.SM_YVIRTUALSCREEN)
hwindc = win32gui.GetWindowDC(hwin)
srcdc = win32ui.CreateDCFromHandle(hwindc)
memdc = srcdc.CreateCompatibleDC()
bmp = win32ui.CreateBitmap()
bmp.CreateCompatibleBitmap(srcdc, width, height)
memdc.SelectObject(bmp)
memdc.BitBlt((0, 0), (width, height), srcdc, (left, top), win32con.SRCCOPY)
signedIntsArray = bmp.GetBitmapBits(True)
img = np.frombuffer(signedIntsArray, dtype='uint8')
img.shape = (height, width, 4)
srcdc.DeleteDC()
memdc.DeleteDC()
win32gui.ReleaseDC(hwin, hwindc)
win32gui.DeleteObject(bmp.GetHandle())
return cv2.cvtColor(img, cv2.COLOR_BGRA2RGB)
b.获取当前屏幕分辨率
def get_screen_size():
import tkinter
screen = tkinter.Tk()
w = screen.winfo_screenwidth() # 获取当前屏幕的宽
h = screen.winfo_screenheight() # 获取当前屏幕的高
return w, h
c.发送图片至QQ邮箱
#! /usr/bin/env python
# coding=utf-8
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
def send_img_to_email(rec_qq, sen_qq, pwd, img_path):
receiver = rec_qq + "@qq.com" # 发送邮件的邮箱
sender = sen_qq + "@qq.com" # 接受邮件的邮箱(可以和上面的一样
pwd = pwd # @qq.com邮箱SMTP的授权码
# wquuvpbunfqoeahe
msg = MIMEMultipart()
msg["Subject"] = "有陌生人来访!" # 邮件的主题
msg["From"] = sender
msg["To"] = receiver
part = MIMEText("请查收陌生人照片!") # 邮件的正文
msg.attach(part)
part = MIMEApplication(open(img_path, 'rb').read())
part.add_header('Content-Disposition', 'attachment', filename=img_path)
msg.attach(part)
s = smtplib.SMTP("smtp.qq.com", timeout=30) # 连接smtp邮件服务器,端口默认是25
s.ehlo()
s.starttls()
s.login(sender, pwd) # 登陆服务器
s.sendmail(sender, receiver, msg.as_string()) # 发送邮件
s.close()
print('邮件发送成功!')
except smtplib.SMTPException:
print('邮件发送失败!')
# 使用案例
if __name__ == '__main__':
qq = '2642898145'
send_img_to_email(qq, qq, 'wquuvpbunfqoeahe', '2.png')
成品
最终合成的代码(可设置每隔多久发送一次:
import time
import cv2
import numpy as np
import win32gui
import win32ui
import win32con
import win32api
# coding=utf-8
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
class computerScreenDetecter(object):
def __init__(self, qq, pwd, img_path, time_cell):
self.qq = qq
self.pwd = pwd
self.img_path = img_path
self.time_cell = time_cell
def get_screen_size(self):
import tkinter
screen = tkinter.Tk()
w = screen.winfo_screenwidth() # 获取当前屏幕的宽
h = screen.winfo_screenheight() # 获取当前屏幕的高
return int(w*1.3), int(h*1.3)
def grab_screen(self, region=None):
hwin = win32gui.GetDesktopWindow()
if region:
left, top, x2, y2 = region
width = x2 - left + 1
height = y2 - top + 1
else:
width = win32api.GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN)
height = win32api.GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN)
left = win32api.GetSystemMetrics(win32con.SM_XVIRTUALSCREEN)
top = win32api.GetSystemMetrics(win32con.SM_YVIRTUALSCREEN)
hwindc = win32gui.GetWindowDC(hwin)
srcdc = win32ui.CreateDCFromHandle(hwindc)
memdc = srcdc.CreateCompatibleDC()
bmp = win32ui.CreateBitmap()
bmp.CreateCompatibleBitmap(srcdc, width, height)
memdc.SelectObject(bmp)
memdc.BitBlt((0, 0), (width, height), srcdc, (left, top), win32con.SRCCOPY)
signedIntsArray = bmp.GetBitmapBits(True)
img = np.frombuffer(signedIntsArray, dtype='uint8')
img.shape = (height, width, 4)
srcdc.DeleteDC()
memdc.DeleteDC()
win32gui.ReleaseDC(hwin, hwindc)
win32gui.DeleteObject(bmp.GetHandle())
return cv2.cvtColor(img, cv2.COLOR_BGRA2RGB)
def pritn_time(self):
import time
time_tuple = time.localtime(time.time())
print("当前时间为: {}年{}月{}日 - {}:{}:{}".format(time_tuple[0], time_tuple[1], time_tuple[2], time_tuple[3],
time_tuple[4],
time_tuple[5]))
def send_img_to_email(self):
sender = self.qq + "@qq.com" # 发送邮件的邮箱(
receiver = self.qq + "@qq.com" # 接受邮件的邮箱 可以和sender的一样
pwd = self.pwd # @qq.com邮箱SMTP的授权码
# wquuvpbunfqoeahe
msg = MIMEMultipart()
msg["Subject"] = "有陌生人来访!" # 邮件的主题
msg["From"] = sender
msg["To"] = receiver
part = MIMEText("请查收陌生人照片!") # 邮件的正文
msg.attach(part)
part = MIMEApplication(open(self.img_path, 'rb').read()) # ''和该.py文件在同一个文件夹下
part.add_header('Content-Disposition', 'attachment', filename=self.img_path)
msg.attach(part)
s = smtplib.SMTP("smtp.qq.com", timeout=30) # 连接smtp邮件服务器,端口默认是25
s.ehlo()
s.starttls()
s.login(sender, pwd) # 登陆服务器
s.sendmail(sender, receiver, msg.as_string()) # 发送邮件
s.close()
print('邮件发送成功!')
except smtplib.SMTPException:
print('邮件发送失败!')
def get_creamerImg(self):
cap = cv2.VideoCapture(0)
time_cell = 1
while time_cell:
success, img = cap.read()
cv2.imwrite('screen_img.png', img)
time_cell -= 1
cap.release()
cv2.destroyAllWindows()
def demo(self):
w, h = self.get_screen_size()
start_time = time.time()
while True:
img = self.grab_screen(region=(0, 0, w, h))
end_time = int(time.time() - start_time)
# 间隔60s发送一次
if end_time % self.time_cell == 0:
self.pritn_time()
cv2.imwrite('screen_img.png', img)
print('电脑屏幕检测准备开始!')
self.send_img_to_email()
print('电脑摄像头检测准备开始!')
self.get_creamerImg()
self.send_img_to_email()
# 使用案例
if __name__ == "__main__":
qq = '2642898145' # 发送者和接受者的QQ都用同一个
kwd = 'wquuvpbunfqoeahe' # QQ邮箱SMTP授权码
img_path = 'screen_img.png' # 写入本地图片路径
time_cell = 60 # 时间间隔多久发送一次截屏 单位:秒(s)
sd = computerScreenDetecter(qq, kwd, img_path, time_cell)
sd.demo()
补充想法:
我们是不是可以添加一个人脸识别,捕捉到摄像头前人的图片之后识别是否是自己或者自己认识的人,如果不是,那么才发送图片警醒自己,如果是,那么告知是谁。
完毕!
制作不易,望点赞+关注+收藏(😊(●'◡'●)
首先进行双目摄像头定标,获取双目摄像头内部的参数后,进行测距;本文的双目视觉测距是基于BM算法。注意:双目定标的效果会影响测距的精准度,建议大家在做双目定标时,做好一些(尽量让误差小)。