之前写了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()
运行的数据记录