使用python opencv延时摄影
使用opencv生成延时摄影视频
以下内容和源码使用openai的chatGPT生成。
下面是一个示例代码,它使用 OpenCV 库在 Python 中实现这个功能。请注意,这个程序需要您先安装 OpenCV 库。
我们设置了摄像头编号为 1,并且创建了一个名为 pic 的文件夹来保存图片。这样,每张保存的图片都会保存到 ./pic 目录下。
我们通过 pathlib.Path 类来创建保存图片的路径,并且使用该类的 mkdir() 方法来创建保存图片的文件夹。这样,您可以通过使用 pathlib 模块来更方便地处理文件路径。
最后可以使用 OpenCV 库来将保存的图片做成视频
点击查看代码
import cv2
import time
from pathlib import Path
import threading
# 设置摄像头的编号,如果您的计算机只有一个摄像头,那么编号就是 0
camera_id = 1
# 打开摄像头
camera = cv2.VideoCapture(camera_id)
# 设置视频的尺寸,帧率和编码方式
video_width = 640
video_height = 480
video_fps = 30
video_fourcc = cv2.VideoWriter_fourcc(*"MJPG")
# 使用时间戳作为视频文件名
timestamp = time.strftime("%Y%m%d%H%M%S", time.localtime())
# 设置要保存图片的路径,如果路径不存在,则创建该路径
save_path = Path(rf"C:\Users\Da\Videos\cameraUSB\Camera-{timestamp}")
save_path.mkdir(parents=True, exist_ok=True)
# print(save_path)
video_file = save_path / f"{timestamp}.avi"
print(video_file)
# 如果视频文件已存在,则打开文件并继续写入
if video_file.exists():
video_writer = cv2.VideoWriter(str(video_file), video_fourcc, video_fps, (
video_width, video_height), isColor=True, isContinuous=True)
# 否则创建文件
else:
video_writer = cv2.VideoWriter(
str(video_file), video_fourcc, video_fps, (video_width, video_height))
while True:
# 从摄像头中捕获一帧图像
ret, frame = camera.read()
# 如果捕获到了一帧图像
if ret:
# 将时间戳显示在画面右上角
timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
cv2.putText(frame, timestamp, (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
# 保存图像
timestamp_cur = time.strftime("%Y%m%d%H%M%S", time.localtime())
filename = save_path / f"{timestamp_cur}.jpg"
# print(filename)
cv2.imwrite(str(filename), frame)
# 将图像缩放到指定的尺寸
frame = cv2.resize(frame, (video_width, video_height))
# 将图像写入视频
video_writer.write(frame)
# 每隔 2 秒保存一张图片
time.sleep(2)
# 关闭摄像头
camera.release()
# 关闭视频写入器
video_writer.release()
# 销毁窗口
cv2.destroyAllWindows()
使用帧差法做移动物体检测
点击查看代码
import cv2
import time
from pathlib import Path
import datetime
# 设置要保存图片的路径,如果路径不存在,则创建该路径
save_path = Path(rf".\imgs")
save_path.mkdir(parents=True, exist_ok=True)
# print(save_path)
# 定义摄像头对象,其参数0表示第一个摄像头
camera = cv2.VideoCapture(1, cv2.CAP_DSHOW)
# 判断视频是否打开
if (camera.isOpened()):
print('Open')
else:
print('摄像头未打开')
# 测试用,查看视频size
size = (int(camera.get(cv2.CAP_PROP_FRAME_WIDTH)),
int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT)))
print('size:' + repr(size))
# 帧率
fps = 5
# 总是取前一帧做为背景(不用考虑环境影响)
pre_frame = None
while (1):
start = time.time()
# 读取视频流
ret, frame = camera.read()
# 转灰度图
gray_lwpCV = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
if not ret:
break
end = time.time()
# 将时间戳显示在画面右上角
timestamp = time.strftime("%Y-%m-%d %H:%M:%S",
time.localtime())
cv2.putText(frame, timestamp, (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)
cv2.imshow("capture", frame)
# 运动检测部分
seconds = end - start
if seconds < 1.0 / fps:
time.sleep(1.0 / fps - seconds)
gray_lwpCV = cv2.resize(gray_lwpCV, (500, 500))
# 用高斯滤波进行模糊处理
gray_lwpCV = cv2.GaussianBlur(gray_lwpCV, (21, 21), 0)
# 如果没有背景图像就将当前帧当作背景图片
if pre_frame is None:
pre_frame = gray_lwpCV
else:
# absdiff把两幅图的差的绝对值输出到另一幅图上面来
img_delta = cv2.absdiff(pre_frame, gray_lwpCV)
# threshold阈值函数(原图像应该是灰度图,对像素值进行分类的阈值,当像素值高于(有时是小于)阈值时应该被赋予的新的像素值,阈值方法)
thresh = cv2.threshold(img_delta, 25, 255, cv2.THRESH_BINARY)[1]
# 膨胀图像
thresh = cv2.dilate(thresh, None, iterations=2)
# findContours检测物体轮廓(寻找轮廓的图像,轮廓的检索模式,轮廓的近似办法)
contours, hierarchy = cv2.findContours(thresh.copy(),
cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
# 设置敏感度
# contourArea计算轮廓面积
if cv2.contourArea(c) < 1000:
continue
else:
# 保存图像
# 使用时间戳作为视频文件名
timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M-%S.%f")
print(f"{timestamp}:出现目标物")
pic_name = save_path / f"pic_{timestamp}.jpg"
cv2.imwrite(str(pic_name), frame)
break
pre_frame = gray_lwpCV
# 等待一段时间,用户按下按键后退出循环
key = cv2.waitKey(1)
if key == ord("q") or key == 27: # 按下Q键或ESC键
break
# release()释放摄像头
camera.release()
# destroyAllWindows()关闭所有图像窗口
cv2.destroyAllWindows()
多线程画面更新、显示与保存
这是一个简单的多线程与CV摄像头结合的示例,使用lock线程锁确保读取的画面是最新的
点击查看代码
import cv2
import threading
import time
# 显示图像的函数
def show_image():
global frame_img
while 1:
with lock:
img = frame_img
cv2.imshow("image", img)
# 等待一段时间,用户按下按键后退出循环
key = cv2.waitKey(1)
if key == ord("q") or key == 27: # 按下Q键或ESC键
break
# 保存图像的函数
def save_image():
global frame_img
while 1:
with lock:
img = frame_img
# 每隔一段时间保存一张图片
time.sleep(1)
# 定义保存图像的文件夹名称
img_folder = "imgs/"
filename = img_folder + time.strftime("%Y%m%d-%H%M%S.jpg")
cv2.imwrite(filename, img)
print(filename)
# 从摄像头读取帧的函数
def update_frame(cap):
global frame_img
while 1:
# 读取摄像头帧
ret, frame = cap.read()
with lock:
frame_img = frame
# cv2.waitKey(1)
# 创建摄像头对象
cap = cv2.VideoCapture(1)
print('打开摄像头成功!')
lock = threading.Lock()
# 定义全局变量 图片帧
frame_img = None
# 创建线程,用于从摄像头读取帧
thread3 = threading.Thread(target=update_frame, args=(cap,))
thread3.start()
time.sleep(1)
thread1 = threading.Thread(target=show_image)
thread1.start()
thread2 = threading.Thread(target=save_image)
thread2.start()
print('线程创建成功!')
# 等待线程结束
thread3.join()
thread1.join()
thread2.join()
# 释放摄像头
cap.release()