openCV開啟高畫質攝像頭卡頓的問題

IT终结者發表於2024-03-15

cv2.VideoCapture(camera_number + cv2.CAP_DSHOW) 是OpenCV在Windows平臺下用於指定使用DirectShow作為影片捕獲後端的一種方式。這裡的 cv2.CAP_DSHOW 是一個常量,表示使用DirectShow(DirectX Show)技術來訪問和控制攝像頭。
cv2.CAP_DSHOW 引數含義:
當你將 cv2.CAP_DSHOW 與攝像頭編號相加時,實際上是告訴OpenCV使用DirectShow框架來開啟並操作指定的攝像頭裝置。
DirectShow是Windows作業系統中用於處理音/影片流的一種API集合,它可以動態構建資料來源到渲染器之間的過濾器鏈,支援多種音訊和影片格式,並具有一定的硬體加速能力。
可替換引數及其意義: 在OpenCV中,針對不同的系統和攝像頭型別,可以設定不同的影片捕獲後端。對於不同平臺,VideoCapture建構函式可以接受以下幾種型別的捕獲器識別符號:
cv2.CAP_ANY (預設值): OpenCV會選擇系統的預設捕獲裝置或框架。在Windows上可能優先選擇VFW (Video for Windows) 或者 DirectShow。
cv2.CAP_VFW (僅限Windows): 使用Video for Windows API。
cv2.CAP_V4L / cv2.CAP_V4L2 (Linux): 使用Video4Linux (V4L) 或 Video4Linux2 (V4L2) 驅動介面。
cv2.CAP_FIREWIRE (某些Linux發行版): 使用IEEE 1394(火線)介面。
cv2.CAP_DC1394 (某些Linux和Mac OS X): 使用IIDC 1394 DC (Digital Camera) 規範。
cv2.CAP_CMU1394 (某些舊版本的OpenCV,現已棄用): 另一種對1394火線相機的支援。
cv2.CAP_QT / cv2.CAP_GSTREAMER / cv2.CAP_FFMPEG 等: 在特定環境中使用其他捕獲框架。
請注意,不是所有平臺都支援上述所有選項,實際可用的選項取決於您安裝的OpenCV版本以及目標作業系統的支援情況。在嘗試使用這些選項前,請確保它們在您的環境下有效且適用。

import time

import numpy as np
import cv2


def video_hd():
    """
    問題:opencv-python 在2k採集模式下,畫面卡頓厲害,而且錄製成功後出現加速播放的效果,實際時常和錄製時長相差太大
    調研:很多攝像頭在高解析度的情況下都不到15幀,以MJPG格式解碼能達到30幀。
    :return:
    """
    start = int(time.time())
    cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)

    cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920) # 設定寬為1920
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080) # 設定高為1080
    cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG')) # 使用設攝像頭錄製高畫質影片的時候一定要設定為MJPG,別的格式無法支援高畫質

    fourcc = cv2.VideoWriter_fourcc(*'MJPG') # 保持的格式
    out = cv2.VideoWriter('{}.avi'.format(str(start)), fourcc, 30.0, (1920, 1080))
    print("按字母 q 結束錄製")
    time1 = time.time()
    while cap.isOpened():
        step = int(time.time())

        ret, frame = cap.read()
        if ret == True:
            out.write(frame)
            cv2.imshow('frame', frame)
            if (cv2.waitKey(1) & 0xFF == ord('q')):
                print(f"花費的時間 {time.time() - time1}")
                break
        else:
            break
    # 資源釋放,在錄製結束後,我們要釋放資源:
    # 釋放資源
    cap.release()
    out.release()
    cv2.destroyAllWindows()


if __name__ == '__main__':
    video_hd()

相關文章