用python写智能监控程序

之前写了Python采用Dos执行命令方式定时运行py程序-CSDN博客笔记本利用Python自动拍摄照片并判断明亮度后按时间保存-CSDN博客,利用笔记本摄像头做监控,保存间隔5分钟的照片。今天,觉得保存的照片太多了,对于上班时间,可以多拍摄一些照片,下班的时间可以少拍一些照片,夜里拍摄间隔时间可以更长,为此采用cron,定时进行拍摄。还有,如果笔记本前没有变化,那么拍摄的照片就没有意义,所有拍摄的照片应该与上一张照片对比,如果没有变化,那么可以不保存。对于一直拍照,还是用数据库来记录拍照的信息,如拍照时间、照片的亮度、图片平均hash码(我用这个来判别照片是否需要保存)等。

一、建立数据库

CREATE TABLE pz (
    id   INTEGER PRIMARY KEY AUTOINCREMENT,
    sj   TEXT,
    furl TEXT,
    ld   INTEGER,
    hash TEXT
);

二、拍照程序

# -*- coding: utf-8 -*-
"""
Created on Thu Jun  6 08:09:26 2024

@author: YBK
"""
import cv2
import os
import imagehash
import datetime
from PIL import Image
import sqlite3
from pathlib import Path

db_filepath = Path(__file__).joinpath("../pz.db").resolve()
def insertdb(sj,furl,ld,hash0): #插入一行数据,包括拍照时间,保存文件地址,照片亮度,hash码
    conn = sqlite3.connect(db_filepath, timeout=10, check_same_thread=False)
    c = conn.cursor()
    insert_query = "INSERT INTO pz(sj,furl,ld,hash) VALUES(?,?,?,?);"
    insert_data = (sj,furl,ld,hash0)
    c.execute(insert_query,insert_data)
    conn.commit()
    c.close()
    conn.close
def gethash(): #获取最后一个hash码
    conn = sqlite3.connect(db_filepath, timeout=10, check_same_thread=False)
    c = conn.cursor()
    cursor = c.execute("select hash from pz where hash <> '' order by id desc limit 0,1;")
    row = cursor.fetchone()
    if row:
        hashstr = row[0]
    else:
        hashstr = ''    
    c.close()
    conn.close
    return hashstr

# 设置拍照参数
frame_width = 960
frame_height = 540
# 初始化摄像头
cap = cv2.VideoCapture(0)  # 0 通常是默认摄像头的标识

# 检查摄像头是否成功打开
if not cap.isOpened():
    print("无法打开摄像头")
    exit()

cap.set(cv2.CAP_PROP_FRAME_WIDTH, frame_width)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, frame_height)
now = datetime.datetime.now()
filename = str(now).replace('-','').replace(':','').replace(' ','').replace('2024','').split('.')[0]
date_str = now.strftime("%Y%m%d")
date_path = 'e:\\sxtpz\\' + date_str
# 读取一帧图像
ret, frame = cap.read()
 
# 如果成功读取图像,进行保存
if ret:        
    frame1 = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) #cv2图片转化为PIL图片
    img = Image.fromarray(frame1) #cv2图片转化为PIL图片
    gray_img = img.convert('L') #转化为灰度照片
    # 计算平均亮度
    avg_brightness = sum(gray_img.getdata()) / (gray_img.width * gray_img.height)
    hash0 = imagehash.average_hash(img) #生成图片的平均hash码
    hashstr = gethash() #获取最后一个hash码
    if avg_brightness < 30 or str(hash0) == hashstr:
        if avg_brightness < 30:
            print("照片是黑暗的,不保存")   
        else:
            print("照片hash码与上一次拍摄的相同,不保存")
        insertdb(now.strftime("%Y-%m-%d %H:%M:%S"),'',int(avg_brightness),str(hash0)) #插入一行不带文件地址的数据
    else:
        if os.path.exists(date_path): #判断本日期的文件夹是否存在,不存在就创建
            pass
        else:
            print("创建文件夹")
            os.makedirs(date_path, exist_ok=True)
        cv2.imwrite(date_path + '\\' + filename + '.jpg', frame) #保存图片
        print("照片已保存到:" + filename + '.jpg 明亮度:' + str(int(avg_brightness)))
        insertdb(now.strftime("%Y-%m-%d %H:%M:%S"),date_path + '\\' + filename + '.jpg',int(avg_brightness),str(hash0)) #插入一行数据
    del(gray_img)
    del(img)
    del(frame1)
else:
    print("无法拍照")


# 释放摄像头
del(frame)

cap.release()
cv2.destroyAllWindows()

三、按调度运行拍照程序

# -*- coding: utf-8 -*-
"""
Created on Mon Aug 12 12:36:25 2024

@author: YBK
"""

from apscheduler.schedulers.blocking import BlockingScheduler
import subprocess

def rundos():
    command = 'conda activate python38' #运行的环境
    try:
        result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        if result.returncode == 0:
            print('38ok ' + result.stdout)
        else:
            print('38err ' + result.stderr)
    except Exception as e:
        print(f'发生异常:{e}')
    command1 = 'python E:\.spyder-py3\拍照0.py'
    try:
        result = subprocess.run(command1, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        if result.returncode == 0:
            print('ok ' + result.stdout)
        else:
            print('err ' + result.stderr)
    except Exception as e:
        print(f'发生异常:{e}')
        
rundos()

sched = BlockingScheduler()
# sched.add_job(rundos, 'interval', minutes=5,) 
sched.add_job(rundos, 'cron', day_of_week='mon-sun', hour='8-11', minute='*/5', second='0') #早上上班时间每5分钟运行一次
sched.add_job(rundos, 'cron', day_of_week='mon-sun', hour='12-13', minute='*/10', second='0') #中午休息时间每10分钟运行一次
sched.add_job(rundos, 'cron', day_of_week='mon-sun', hour='14-18', minute='*/5', second='0') #下午上班时间每5分钟运行一次
sched.add_job(rundos, 'cron', day_of_week='mon-sun', hour='19-23', minute='*/10', second='0') #晚上每10分钟运行一次
sched.add_job(rundos, 'cron', day_of_week='mon-sun', hour='0-8', minute='*/15', second='0') #凌晨每15分钟运行一次
sched.start()        

运行的数据记录

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值