【间谍安全】基于OpenCv的智能防盗监控系统

一、间谍安全🍉

        间谍出行保证自己的安全也是第一位。我们可以使用智监系统到达以下目的:

  • 智能监测出现在我们电脑前的人。
  • 偷偷观察一下有谁会在我们不在场的时候想发现我们在做什么,这个时候我们可能已经被怀疑了!🤫

“ 编程改造世界!”

        对于本栏,我们要实现的正是智能防盗监控系统,想要实时监测电脑屏幕与摄像头前的人,我们必须满足以下几个条件:

  1. 🎈当前屏幕的分辨率,以方便之后调整电脑屏幕截图的尺寸。
  2. 🎈间隔的获取:(1)屏幕画面的截图(2)开启摄像头捕捉到的一帧图像
  3. 🎈将目标截图发送到我们的邮箱。
  4. 🎈在我们离开自己的电脑后,启动算法。

          是不是超级简单呢?接下来,我们将一一实现它们,并将他们整合为一个打包好的类。


二、项目演示🍉

2.1 电脑屏幕截屏🎈

2.2 摄像头截屏🎈 

三、一步一步来编程实现它们👑

        不着急Copy代码,最后面有一个打包好的类,方便大家使用。这里是拆解代码用于解释各个函数的意思。

3.1 我们需要获取当前屏幕的分辨率,以方便之后调整电脑屏幕截图的尺寸。🎈

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)

2、我们需要间隔的获取,屏幕画面的截图开启摄像头捕捉到的一帧图像。🎈


def get_screen_size():
    import tkinter
    screen = tkinter.Tk()
    w = screen.winfo_screenwidth()      # 获取当前屏幕的宽
    h = screen.winfo_screenheight()     # 获取当前屏幕的高
    return w, h

3、我们需要将我们获得的截图发送到我们的邮箱。


#! /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)

    try:
        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)

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

五、补充想法🍉

5.1 人脸识别🎈

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

NOTE:OpenCV的官方GitHub仓库地址是:https://github.com/opencv/opencv

你可以在该仓库中找到相关的文件。具体来说,人脸识别器(CascadeClassifier)所需的级联分类器文件通常位于 data/haarcascades 目录下。而人脸检测器(face_cascade.detectMultiScale)使用的级联分类器文件是 haarcascade_frontalface_default.xml

你可以通过以下链接直接访问该文件: https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_frontalface_default.xml

请注意,为了使用人脸识别器和人脸检测器,你需要将级联分类器文件下载到本地,并在代码中指定正确的文件路径。

import cv2
import numpy as np

# 加载OpenCV的人脸识别器
face_cascade = cv2.CascadeClassifier('path/to/haarcascade_frontalface_default.xml')

# 加载训练好的人脸识别模型(如LBPH或Eigenfaces)
face_recognizer = cv2.face.LBPHFaceRecognizer_create()
face_recognizer.read('path/to/trained_model.yml')

# 加载图像
image = cv2.imread('path/to/image.jpg')

# 将图像转换为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 使用人脸检测器检测人脸
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))

# 对每个检测到的人脸进行识别
for (x, y, w, h) in faces:
    # 提取人脸区域
    face_roi = gray[y:y+h, x:x+w]

    # 进行人脸识别
    label, confidence = face_recognizer.predict(face_roi)

    # 绘制标签和置信度值在图像上
    text = f"Label: {label}, Confidence: {confidence}"
    cv2.putText(image, text, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
    cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 3)

# 显示结果
cv2.imshow('Face Recognition', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

5.2 人脸检测🎈

        添加一个人脸检测,每当检测到人脸才进行截图的操作。

NOTE:在下面的代码中,你需要将'path/to/haarcascade_frontalface_default.xml'替换为OpenCV库中实际的haar级联分类器文件路径。你可以在OpenCV的官方GitHub仓库中找到这个文件(https://github.com/opencv/opencv/tree/master/data/haarcascades)。

import cv2
import numpy as np

# 加载OpenCV的人脸检测器
face_cascade = cv2.CascadeClassifier('path/to/haarcascade_frontalface_default.xml')

# 加载图像
image = cv2.imread('path/to/image.jpg')

# 将图像转换为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 使用人脸检测器检测人脸
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))

# 在图像上绘制人脸矩形框
for (x, y, w, h) in faces:
    cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 3)

# 显示结果
cv2.imshow('Face Detection', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

完毕! 

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

  • 9
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大气层煮月亮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值