使用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()

posted @ 2022-12-07 13:37  Dapenson  阅读(329)  评论(0编辑  收藏  举报