2015-01-29 2 views
6

한 번에 한 프레임을 처리하려고하는 비디오 파일이 있습니다. VideoCapture 클래스를 사용하여 다음 유형의 코드로 읽기 작업을 시도했습니다. 문제는 비디오 파일을 초당 25 프레임으로 녹화하면 독서가 같은 속도로 진행된다는 것입니다. 컴퓨터에서 최대한 빨리 프레임을 가져 오는 방법은 무엇입니까?파일 프레임 속도보다 빠른 Python OpenCV로 비디오 파일을 처리하는 방법은 무엇입니까?

비디오 스트림을 처리 한 다음 파일에 저장할 계획입니다.

import cv2 
import sys 
import time 

cap = cv2.VideoCapture(sys.argv[1]) 
start = time.time() 

counter = 0 
while True: 
    counter += 1; 
    image = cap.read()[1] 
    if counter %25 == 0: 
     print "time", time.time() - start 

출력 : 25 프레임마다 한 번 타임 스탬프를 인쇄합니다. 타임 라인이 매 라인 => 프로그램에서 초당 약 25 프레임을 처리 할 때 거의 정확하게 1 초씩 변하는 것을 볼 수 있습니다. 이 비디오 파일은 25 프레임/초입니다.

time 1.25219297409 
time 2.25236606598 
time 3.25211691856 
time 4.25237703323 
time 5.25236296654 
time 6.25234603882 
time 7.252161026 
time 8.25258207321 
time 9.25195503235 
time 10.2523479462 

아마도 VideoCapture는 이러한 종류의 작업에 잘못된 API이지만 아마도 대신 무엇을 사용해야합니까?

Linux, Fedora 20, opencv-python 2.4.7 및 python 2.7.5를 사용합니다.

+0

"문제는 비디오 파일을 초당 25 프레임으로 녹화하면 독서가 같은 속도로 진행된다는 것입니다. 그것은 원래의 프레임 속도를 고려하지 않습니다. 위의 코드는 이미 최대한 빨리 읽습니다. – berak

+0

"아마 VideoCapture가 이런 종류의 작업을하는 잘못된 API입니다."- 네, 아마도 그럴 것입니다. 그것은 단지 이미지를 획득하는 유틸리티 일 뿐이며 더 이상은 아닙니다. – berak

+0

@berak 읽기 속도는 30fps 비디오의 경우 30fps, 15fps 비디오의 경우 15fps, CPU 유휴 상태가 많은 것 같습니다. –

답변

6

opencv가 으로 컴파일되고 ffmpeg가 지원되지 않는 경우 (즉, cv::VideoCapture >> image은 녹화 된 비디오의 프레임 속도로 고정) 재현 할 수 있습니다. ffmpeg 지원 opencv 을 컴파일하면 컴퓨터에서 허용하는 한 빨리 파일에서 이미지를 읽을 수 있습니다. 나는 ffmpeg가 없다면 opencv는 gstreamer를 사용하고 영화를 재생하는 것처럼 비디오 파일을 본질적으로 취급한다고 생각한다.

Linux를 사용하는 경우 this link에는 opencv에 대한 ffmpeg 지원을 설치하기 위해 설치해야하는 패키지가 표시됩니다.

+0

필자는 실제로 VideoCapture에서 프레임 속도보다 빠르게 읽을 수 있음을 확인할 수 있지만 ffmpeg로 컴파일 된 OpenCV 3.0을 사용하고 있습니다. –

+0

그게 해결책 인 것 같습니다. 감사 –

0

아직 시도하지는 않았지만 한정된 길이의 기기에 저장된 비디오 파일 (즉, 라이브 웹캠이 아님)에서 작동 할 수 있다고 생각합니다. 예상 할 수있는 단점은 알고리즘이 충분히 빠른 처리를하지 못하면 프레임을 건너 뛸 수 있지만 다음 프레임을 읽지 않을 것입니다. 일반적으로 VideoCapture는 FPS보다 느리게 읽을 수 있지만 더 빨리 읽을 수는 없다고 생각합니다. 그걸 인용하지 말아라. 내가 알아 차린 것 같아.

VideoCapture::set()을 사용하면 FPS를 컴퓨터의 파일보다 빠르게 변경할 수 있습니다. CV_CAP_PROP_FPS는 변경하려는 것입니다.

VideoCapture::get() 기능을 사용하여 fps가 제대로 설정되었는지 확인하십시오.