close

Python 結合 OpenCV 與 Picamera2:影片錄製與即時影像處理

本文將介紹如何在 Python 中使用 OpenCV 與 Picamera2 實現即時影像處理與影片錄製,並提供模擬 OpenCV 的 cv2.VideoCapture 的解決方案。

基於 OpenCV 的基本相機操作與影片錄製

以下程式碼使用 OpenCV 的 cv2.VideoCapture 從相機捕捉影像,進行即時顯示並保存為 MP4 格式的影片:


import cv2

ESC = 27
cap = cv2.VideoCapture(0)
ratio = cap.get(cv2.CAP_PROP_FRAME_WIDTH) / cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
WIDTH = 400
HEIGHT = int(WIDTH / ratio)

fourcc = cv2.VideoWriter_fourcc(*'MP4V')
out = cv2.VideoWriter('video.mp4', fourcc, 30, (WIDTH, HEIGHT))

while True:
    ret, frame = cap.read()
    frame = cv2.resize(frame, (WIDTH, HEIGHT))
    frame = cv2.flip(frame, 1)

    out.write(frame)

    cv2.imshow('frame', frame)
    if cv2.waitKey(1) == ESC:
        break

cap.release()
out.release()
cv2.destroyAllWindows()
            

此程式透過 cv2.VideoWriter 寫入影片,並提供即時預覽畫面。適合用於一般電腦相機的操作。

改用 Raspberry Pi 的 Picamera2 套件

Raspberry Pi 提供了全新的 Picamera2 套件,支援現代化的相機操作,以下是改寫程式碼:


from picamera2 import Picamera2, Preview
import cv2
import numpy as np

ESC = 27
picam2 = Picamera2()
camera_config = picam2.create_preview_configuration(main={"size": (640, 480)})
picam2.configure(camera_config)
picam2.start()

WIDTH = 400
HEIGHT = int(WIDTH * 480 / 640)
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('video.mp4', fourcc, 30, (WIDTH, HEIGHT))

while True:
    frame = picam2.capture_array()
    frame = cv2.resize(frame, (WIDTH, HEIGHT))
    frame = cv2.flip(frame, 1)
    out.write(frame)

    cv2.imshow('frame', frame)
    if cv2.waitKey(1) == ESC:
        break

picam2.stop()
out.release()
cv2.destroyAllWindows()
            

這段程式碼更適合 Raspberry Pi 使用,並能更靈活地調整解析度與影像處理。

模擬 OpenCV 的 cv2.VideoCapture 行為

若想統一使用 cv2.VideoCapture 的介面,可以創建一個自訂類別如下:


from picamera2 import Picamera2
import cv2
import numpy as np

class PiCameraCapture:
    def __init__(self, resolution=(640, 480)):
        self.picam2 = Picamera2()
        camera_config = self.picam2.create_preview_configuration(main={"size": resolution})
        self.picam2.configure(camera_config)
        self.picam2.start()
        self.opened = True
        self.resolution = resolution

    def isOpened(self):
        return self.opened

    def read(self):
        if not self.opened:
            return False, None
        frame = self.picam2.capture_array()
        return True, frame

    def release(self):
        if self.opened:
            self.picam2.stop()
            self.opened = False

cap = PiCameraCapture(resolution=(640, 480))
if not cap.isOpened():
    print("Error: Unable to open camera.")
    exit()

fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('video.mp4', fourcc, 30, (400, 300))

while True:
    ret, frame = cap.read()
    if not ret:
        break

    frame = cv2.resize(frame, (400, 300))
    frame = cv2.flip(frame, 1)
    cv2.imshow('frame', frame)
    out.write(frame)

    if cv2.waitKey(1) == ESC:
        break

cap.release()
out.release()
cv2.destroyAllWindows()
            

此類別的設計模擬了 cv2.VideoCapture 的行為,使您可以無縫整合到現有程式中。

arrow
arrow
    創作者介紹
    創作者 liusming 的頭像
    liusming

    劉老師的跨域創想工坊

    liusming 發表在 痞客邦 留言(0) 人氣()