簡體   English   中英

OpenCV-n幀后讀取

[英]OpenCV- Reading after n frames

我寫了以下代碼

import cv2
import datetime
import time
import pandas as pd

cascPath = 'haarcascade_frontalface_dataset.xml'  # dataset
faceCascade = cv2.CascadeClassifier(cascPath)

video_capture = cv2.VideoCapture('video1.mp4')

frames = video_capture.get(cv2.CAP_PROP_FRAME_COUNT) 
fps = int(video_capture.get(cv2.CAP_PROP_FPS)) 

print(frames) #1403 frames
print(fps) #30 fps
# calculate duration of the video 
seconds = int(frames / fps) 
print("duration in seconds:", seconds)  #46 seconds


df = pd.DataFrame(columns=['Time(Seconds)', 'Status'])
start = time.time()
print(start)
n=5
while True:
    
    ret, frame = video_capture.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #converts frame to grayscale image
    faces = faceCascade.detectMultiScale(
                gray, scaleFactor=1.1,
                minNeighbors=5,
                minSize=(30, 30),
                flags=cv2.FONT_HERSHEY_SIMPLEX
        )
    if len(faces) == 0:
        print(time.time()-start, 'No Face Detected')
        df = df.append({'Time(Seconds)': (time.time()-start) , 'Status':'No Face detected' }, ignore_index=True)
    else: 
        print(time.time()-start, 'Face Detected')
        df = df.append({'Time(Seconds)':(time.time()-start), 'Status':'Face Detected' }, ignore_index=True)

    # Draw a rectangle around the faces
    for (x, y, w, h) in faces:
        cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)


    # Display the resulting frame
    cv2.imshow('Video', frame)
    df.to_csv('output.csv', index = False)
    if cv2.waitKey(1) & 0xFF == ord('q'):
            # print(df.head(2))
            break


# When everything is done, release the capture
video_capture.release()
cv2.destroyAllWindows()

如果你想下載我正在制作的視頻,你可以從這里下載

這里下載 haar 級聯 XML 文件

我對此有幾個疑問。

  1. 目前它在視頻的所有 1403 幀上運行,我想對其進行優化,使其在每n幀后運行推理,這是可定制的。 在代碼中我提到了 n = 5。 因此,如果 n = 5。幀數應為 1403/5 = 280
  2. 我的 CSV 中的時間戳不准確,我希望它們與視頻相關。 基本上,第一列 (Time(Seconds) 應該指定視頻中的時間,並且狀態應該確定當時幀的狀態(檢測到/未檢測到),Time(second) 列應該在 46 秒左右結束,這是視頻的長度。
  3. 我的 cv2.imshow 正在顯示一個大約 2 倍速度的視頻,我相信我可以通過使用 cv2.imKey() 來控制速度,cv2.waitKey 的最佳參數應該是什么,以便我獲得與 output 類似的速度視頻.

感謝您完成整個問題

如果您想讀取每個“n”幀,可以將 VideoCapture.read() 調用包裝在這樣的循環中:

for a in range(n):
    ret, frame = video_capture.read();

對於 csv 文件中的時間戳,如果它隨數據集一起提供,我會相信的。 相機可能沒有以一致的幀速率進行捕捉。 如果您認為幀速率是一致的並且想要自己生成時間戳,您可以跟蹤您已經經歷了多少幀並將視頻長度除以它。 (即在第 150 幀,時間戳將為 (150 / 1403) * 46 秒)

cv2.imshow() 只顯示與循環運行一樣快的幀。 這主要是通過 cv2.waitKey(milliseconds) 控制的。 如果您認為您在循環中進行的處理所花費的時間可以忽略不計,您可以將 waitKey 中的時間設置為 ((n / 1403) * 46 * 1000)。 否則,您應該使用 python 時間模塊來跟蹤處理需要多長時間並從等待中減去該時間。

編輯:

對不起,我應該對第一部分更清楚。 那個 for 循環只有 VideoCapture.read() 行,沒有別的。 這樣,您將讀取“n”幀,但只處理每“n”幀中的一個。 這並沒有取代您已經擁有的整個 while 循環。 您只是使用 for 循環來轉儲要跳過的幀。

哦,您還應該檢查 read() 的返回值。

if not ret:
    break;

如果沒有該檢查,該程序可能會在視頻結束時崩潰。

暫無
暫無

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

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