Python实现指定区域桌面变化监控并报警

news/2024/10/30 15:20:54/

在这篇博客中,我们将使用Python编程语言和一些常用的库来实现一个简单的区域监控和变化报警系统。我们将使用Tkinter库创建一个图形界面,允许用户选择监控区域,并使用OpenCV库进行图像处理和相似性比较,以检测区域内的变化,并通过播放声音进行报警。

实现效果

运行程序后可以看到一个菜单界面
在这里插入图片描述
点击开始识别按钮后可以选择你想要监控的区域
在这里插入图片描述
如图所示红色部分是点击开始按钮后拖动鼠标会显示的选择范围框,选择好区域后就开始识别该区域前后5秒内的变化。
程序还可以切换模式,可以监控摄像头画面的视频是否有变化,有变化也会报警。
程序运行后
在这里插入图片描述

准备工作

在开始之前,确保你已经安装了Python以及以下所需的库:

  • tkinter: 用于创建图形界面
  • numpy: 用于处理图像数据
  • cv2 (OpenCV): 用于图像处理和相似性比较
  • pyautogui: 用于截取屏幕图像
  • pygame: 用于播放声音
  • PIL (Python Imaging Library): 用于图像处理

你可以使用pip命令来安装这些库:

pip install tkinter numpy opencv-python pyautogui pygame pillow

选择监控区域

首先,让我们创建一个函数来选择监控区域。我们使用Tkinter库创建一个全屏的图形窗口,让用户通过鼠标点击和拖拽来选择监控区域。我们将保存选定的区域的坐标以供后续使用。

import tkinter as tk
from PIL import Image, ImageTkstart_x, start_y, end_x, end_y = None, None, None, Nonedef select_screen_region():global start_x, start_y, end_x, end_ydef on_press(event):global start_x, start_ystart_x, start_y = event.x, event.ydef on_move(event):global end_x, end_yend_x, end_y = event.x, event.ycanvas.coords(rect, start_x, start_y, end_x, end_y)def on_release(event):global end_x, end_yend_x, end_y = event.x, event.ycanvas.coords(rect, start_x, start_y, end_x, end_y)root = tk.Tk()root.title("选择监控区域")root.attributes('-fullscreen', True)screenshot = pyautogui.screenshot()screenshot.save('desktop_screenshot.png', format='png')canvas = tk.Canvas(root, bg='white')canvas.pack(fill=tk.BOTH, expand=True)desktop_image = ImageTk.PhotoImage(file='desktop_screenshot.png')canvas.create_image(0, 0, anchor=tk.NW, image=desktop_image)rect = canvas.create_rectangle(0, 0, 0, 0, outline='red')canvas.bind("<ButtonPress-1>", on_press)canvas.bind("<B1-Motion>", on_move)canvas.bind("<ButtonRelease-1>", on_release)root.mainloop()

调用select_screen_region()函数后,会弹出一个全屏的窗口,你可以通过鼠标点击和拖拽来选择监控区域。选定区域后,关闭窗口即可。

监控区域变化

接下来,我们将创建一个函数来监控选定区域内的变化。我们将使用OpenCV库对图像进行处理,并使用相似性比较来检测区域内的变化。如果检测到较大的变化,我们将播放声音进行报警。

import cv2
import numpy as np
import threading# 初始化pygame库
pygame.init()
pygame.mixer.init()# 全局变量,加载MP3文件
def load_alarm_sound(file_path):try:pygame.mixer.music.load(file_path)except pygame.error:print(f"无法加载音频文件:{file_path}")# 封装一个播放MP3警报的函数
def play_alarm():try:# 播放MP3文件pygame.mixer.music.play()except pygame.error:print("播放警报音频失败")# 调用load_alarm_sound函数,加载警报音频
load_alarm_sound("警报声.mp3")should_exit = False
is_alarm = False
prev_frame_image, current_frame_image = None, Nonedef monitor(data_source):global should_exit, is_alarm, prev_frame_image, current_frame_imageif data_source == "screenshot":prev_frame = capture_screen()elif data_source == "camera":cap = cv2.VideoCapture(0)prev_frame = capture_video_frame(cap)while not should_exit:current_frame = Noneif data_source == "screenshot":current_frame = capture_screen()elif data_source == "camera":current_frame = capture_video_frame(cap)if current_frame is not None:prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)current_gray = cv2.cvtColor(current_frame, cv2.COLOR_BGR2GRAY)similarity = ssim(prev_gray, current_gray)threshold = 0.95if similarity < threshold and not is_alarm:print("检测到较大变化,进行报警!")is_alarm = Trueplay_alarm()# 保存变化前后的照片prev_frame_image = prev_frame.copy()current_frame_image = current_frame.copy()# 在5秒后重置is_alarm标志threading.Timer(5, reset_alarm_flag).start()else:print("没有变化")# 更新前一帧图像prev_frame = current_frametime.sleep(5)  # 等待5秒后再获取下一帧# 释放资源if data_source == "camera":cap.release()cv2.destroyAllWindows()def start_recognition():global should_exitshould_exit = Falseprint("开始监控")th_monitor = threading.Thread(target=monitor, args=("screenshot",))th_monitor.daemon = Trueth_monitor.start()def end_program():global should_exitshould_exit = Trueprint("结束程序")sys.exit(1)

现在,我们已经准备好了选择监控区域和监控区域变化的功能。你可以将它们集成到完整的应用程序中,例如创建一个Tkinter界面,提供开始监控和结束程序的按钮。

import sys
import tkinter as tk
import time
import cv2
import numpy as np
import pyautogui
import pygame
from skimage.metrics import structural_similarity as ssim
from PIL import Image, ImageTk# ... 在此添加上面的选择监控区域和监控区域变化的函数 ...# 创建主窗口
root = tk.Tk()
root.title("区域监控和变化报警")# 添加按钮
btn_start = tk.Button(root, text="开始监控", command=start_recognition)
btn_end = tk.Button(root, text="结束程序", command=end_program)# 使用pack布局并设置side参数为LEFT实现横向排列
btn_start.pack(side=tk.LEFT, padx=10, pady=10)
btn_end.pack(side=tk.LEFT, padx=10, pady=10)# 进入事件循环
root.mainloop()

这样,我们就实现了一个简单的区域监控和变化报警系统。当你点击"开始监控"按钮后,可以选择监控区域,然后程序会持续监测该区域的变化,并在检测到较大变化时进行报警。点击"结束程序"按钮后,程序将退出。希望这篇博客对你有所帮助,欢迎探索更多有趣的Python项目!


http://www.ppmy.cn/news/991428.html

相关文章

中文大模型评估数据集——C-Eval

C-EVAL: A Multi-Level Multi-Discipline Chinese Evaluation Suite for Foundation Models https://arxiv.org/pdf/2305.08322v1.pdfhttps://github.com/SJTU-LIT/cevalhttps://cevalbenchmark.com/static/leaderboard.html Part1 前言 怎么去评估一个大语言模型呢? 在广泛…

Rust-IO

use std::io::Write; fn main() {/*std::io::stdin() 返回标准输入流stdin的句柄。read_line() stdin的句柄的一个方法&#xff0c;从标准输入流中读取一行数据返回一个Result枚举。会自动删除行尾的换行符\n。unwrap() 是一个帮助的方法&#xff0c;简化恢复错误的处理。返回R…

计算列-mysql8

什么叫计算列呢&#xff1f; 简单来说就是某一列的值是通过别的列计算得来的。例如&#xff0c;a列值为1、b列值为2&#xff0c;c列 不需要手动插入&#xff0c;定义ab的结果为c的值&#xff0c;那么c就是计算列&#xff0c;是通过别的列计算得来的。 在MySQL 8.0中&#xff…

基于RASC的keil电子时钟制作(瑞萨RA)(6)----定时器驱动数码管

基于RASC的keil电子时钟制作6_定时器驱动数码管 概述硬件准备视频教程选择定时器定时器做计数器配置定时器回调函数timer_smg.ctimer_smg.h演示效果主程序 概述 要想让每个数码管显示不同的数字&#xff0c;但是数码管必须依次地被持续驱动&#xff0c;数码管之间的刷新速度应…

前端技术周刊 2023-07-30:Promise.withResolvers 进入 Stage3

项目地址&#xff1a;olivewind/weekly[1] 微信公众号&#xff1a;依赖注入 发布时间&#xff1a;2023.07.30 本周内容&#xff1a;资讯x2、开源x8、文章x4 动态 Promise.withResolvers 进入 Stage3 某些情况下需要在 Promise 外部获取 resolve 和 reject 句柄&#xff0c;我们…

单链表的多语言表达:C++、Java、Python、Go、Rust

单链表 是一种链式数据结构&#xff0c;由一个头节点和一些指向下一个节点的指针组成。每个节点包含一个数据元素和指向下一个节点的指针。头节点没有数据&#xff0c;只用于表示链表的开始位置。 单链表的主要操作包括&#xff1a; 添加元素&#xff1a;在链表的头部添加新…

Python语法(二、内置函数)

数学计算库 Python ​math ​模块提供了许多对浮点数的数学运算函数。 Python ​cmath ​模块包含了一些用于复数运算的函数。 import math 内置函数 关键字 自定义函数 Python函数的定义。定义函数需要用def 关键字实现&#xff0c;具体的语法格式如下&#xff1a; def 函…

k8s证书更新,kubeadm安装的K8S证书过期后无法使用后证书更新方法

k8s证书更新 1. 查看证书过期时间 #通过文件查看证书过期时间 for item in find /etc/kubernetes/pki -maxdepth 2 -name "*.crt";do openssl x509 -in $item -text -noout| grep Not;echo $item;done #通过命令查看证书过期时间 kubeadm certs check-expirationk8…