簡體   English   中英

使用 Python OpenCV cv2.VideoCapture() 直接以灰度讀取視頻幀

[英]Read video frame directly in grayscale with Python OpenCV cv2.VideoCapture()

我正在使用 OpenCV。 我有一個視頻文件,我想以灰度讀取它,而不是轉換為灰度的每一幀。 IE

cap = cv2.VideoCapture(VIDEO_PATH)

results = {}
curr_frame = 0
start = time.time()
while(cap.isOpened()):
    # Capture frame-by-frame
    ret, frame = cap.read()
    if ret == True:
        curr_frame+=1
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

我不想這樣做,而是想像我們在圖像中那樣直接以灰度讀取它,即

im_gray = cv2.imread('grayscale_image.png', cv2.IMREAD_GRAYSCALE)

現在在檢查文檔時,我發現讀取函數“該方法/函數在一次調用中結合了 VideoCapture::grab() 和 VideoCapture::retrieve()。” 在檢索內部,我們可以傳遞一個標志值。 是否可以將其與 read 結合並以灰度讀取而不是顯式轉換?

我試着做

ret, frame = cap.read(flag=0)

但它不是有效的關鍵字參數。

error: OpenCV(4.5.5) :-1: error: (-5:Bad argument) in function 'read'
> Overload resolution failed:
>  - 'flag' is an invalid keyword argument for VideoCapture.read()
>  - 'flag' is an invalid keyword argument for VideoCapture.read()

但是我可以在cap.read()中傳入任何隨機數並且它可以工作。

cap.read(-4)

我一直在尋找 Python 中的源代碼,但在 github 上找不到該函數的 Python 源代碼。

根據VideoCaptureModes文檔,有四種可能的模式:

cv2.CAP_MODE_BGR - BGR24 (default)
cv2.CAP_MODE_RGB - RGB24
cv2.CAP_MODE_GRAY - Y8
cv2.CAP_MODE_YUYV - YUYV

另請注意:

目前,這些僅通過 libv4l 后端支持。

因此,要使用cv2.VideoCapture()直接將視頻幀讀取為灰度,您必須使用cv2.CAP_MODE_GRAY將模式設置為灰度,如下所示:

capture = cv2.VideoCapture(0)
possible = capture.set(cv2.CAP_PROP_MODE, cv2.CAP_MODE_GRAY)
print(possible)

# IMPORTANT: Check this value to see if it's supported by your system

您必須檢查返回的bool值是否可行,因為您的操作系統、相機、硬件或后端可能支持也可能不支持。 如果返回值為False或者您收到這樣的錯誤

AttributeError:模塊 'cv2' 沒有屬性 'CAP_MODE_GRAY'

那么不幸的是,您的系統不可能,您可以做的最好的事情是在檢索幀后使用cv2.cvtColor轉換為灰度。


這是一個從網絡攝像頭直接將幀讀取為灰度的工作示例

import multiprocessing as mp
import cv2, time

def capture_frames():
    capture = cv2.VideoCapture(0)
    possible = capture.set(cv2.CAP_PROP_MODE, cv2.CAP_MODE_GRAY)
    print(possible)

    # FPS = 1/X, X = desired FPS
    FPS = 1/120
    FPS_MS = int(FPS * 1000)

    while True:
        # Ensure camera is connected
        if capture.isOpened():
            (status, frame) = capture.read()
            
            # Ensure valid frame
            if status:
                cv2.imshow('frame', frame)
            else:
                break
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
            time.sleep(FPS)

    capture.release()
    cv2.destroyAllWindows()

if __name__ == '__main__':
    print('Starting video stream')
    capture_process = mp.Process(target=capture_frames, args=())
    capture_process.start()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM