相关文章推荐
难过的打火机  ·  sencha cmd ...·  5 月前    · 
严肃的香菇  ·  使用Hadoop API 解压缩 ...·  6 月前    · 
博学的紫菜  ·  python ...·  1 年前    · 

学习前言


想要实时监测电脑屏幕与摄像头前的人,我们必须满足以下几个条件:一、我们需要获取当前屏幕的分辨率,以方便之后调整电脑屏幕截图的尺寸。二、我们需要间隔的获取(while True)此时界面的截图和摄像头捕捉到的一帧图像。三、我们需要将我们获得的截图发送到我们的邮箱。


效果图


屏幕截屏:


1dc618a0ed9580ce8bfa6facb208c08f.png


屏幕前的人:


5d4c6812c8535adbb050f4ddf2e1bce8.png


各个功能代码详解:


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()


补充想法:


我们是不是可以添加一个人脸识别,捕捉到摄像头前人的图片之后识别是否是自己或者自己认识的人,如果不是,那么才发送图片警醒自己,如果是,那么告知是谁。


完毕!


制作不易,望点赞+关注+收藏(😊(●'◡'●)


Windows下使用QT+OpenCV完成人脸检测(获取摄像头的数据进行检测)_解决内存释放问题
Windows下使用QT+OpenCV完成人脸检测(获取摄像头的数据进行检测)_解决内存释放问题
基于OpenCV的双目摄像头测距(误差小)
首先进行双目摄像头定标,获取双目摄像头内部的参数后,进行测距;本文的双目视觉测距是基于BM算法。注意:双目定标的效果会影响测距的精准度,建议大家在做双目定标时,做好一些(尽量让误差小)。