【问题标题】:OpenCV- Reading after n framesOpenCV-n帧后读取
【发布时间】:2021-04-25 03:40:25
【问题描述】:

我写了以下代码

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

如果你想下载我正在制作的视频,可以从here下载

here下载haar cascade XML文件

我对此有一些疑问。

  1. 目前它在视频的所有 1403 帧上运行,我想对其进行优化,使其在每个 n 帧之后运行推理,这是可定制的。在代码中我提到了 n = 5。因此,如果 n = 5。帧数应为 1403/5 = 280
  2. CSV 中的时间戳不准确,我希望它们与视频相关。基本上,第一列(时间(秒)应指定视频中的时间,状态应确定当时帧的状态(检测到/未检测到),时间(秒)列应在 46 秒左右结束,这是视频的长度。
  3. 我的 cv2.imshow 正在显示一个大约 2 倍速度的视频,我相信我可以通过使用 cv2.imKey() 来控制速度,cv2.waitKey 的最佳参数应该是什么,这样我才能获得类似的速度视频作为输出。

感谢您回答整个问题

【问题讨论】:

    标签: python opencv machine-learning image-processing computer-vision


    【解决方案1】:

    如果您想读取每 '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;
    

    如果没有该检查,程序可能会在视频结束时崩溃。

    【讨论】:

    • 你提到的for循环只会捕获n帧,对吧。我的意思是,当 for 循环遍历 n 个 vakues 时,它只会捕获 n 帧。所以第一次迭代是 a=1,第二次是 a=2,第 n 次是 a=n
    猜你喜欢
    • 2014-05-07
    • 1970-01-01
    • 2017-05-03
    • 2016-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多