Cách biết tổng số Frame trong một tệp (.avi) thông qua Python bằng cách sử dụng mô-đun cv mở.
Nếu có thể, tất cả thông tin (độ phân giải, khung hình / giây, thời lượng, v.v.) mà chúng tôi có thể nhận được về một tệp video thông qua việc này.
Câu trả lời:
Với phiên bản OpenCV mới hơn (tôi sử dụng 3.1.0), nó hoạt động như sau:
import cv2
cap = cv2.VideoCapture("video.mp4")
length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
print( length )
Và tương tự cho các thuộc tính video khác cv2.CAP_PROP_*
import cv2
cap = cv2.VideoCapture(fn)
if not cap.isOpened():
print "could not open :",fn
return
length = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT))
width = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.cv.CV_CAP_PROP_FPS)
xem ở đây để biết thêm thông tin.
Ngoài ra, tất cả đều có muối, không phải tất cả các đạo cụ đó đều là bắt buộc, một số có thể không có sẵn với codec chụp / video của bạn
Đây là cách nó hoạt động với Python 3.6.5 (trên Anaconda) và OpenCV 3.4.2. [Lưu ý]: Bạn cần bỏ "CV_" khỏi "CV_CAP_PROP_xx" cho bất kỳ thuộc tính nào như được cung cấp trên trang web OpenCV chính thức .
import cv2
cap = cv2.VideoCapture("video.mp4")
property_id = int(cv2.CAP_PROP_FRAME_COUNT)
length = int(cv2.VideoCapture.get(cap, property_id))
print( length )
length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
Có hai phương pháp để xác định số khung hình trong tệp video
Phương pháp # 1 nhanh chóng và dựa vào chức năng thuộc tính video của OpenCV, chức năng này gần như xác định ngay lập tức số lượng khung hình trong tệp video. Tuy nhiên, có một sự đánh đổi về độ chính xác vì nó phụ thuộc vào phiên bản OpenCV và codec video của bạn. Mặt khác, việc đếm thủ công từng khung hình sẽ chính xác 100% mặc dù nó sẽ chậm hơn đáng kể. Đây là một hàm cố gắng thực hiện Phương pháp số 1 theo mặc định, nếu không thành công, nó sẽ tự động sử dụng Phương pháp số 2
def frame_count(video_path, manual=False):
def manual_count(handler):
frames = 0
while True:
status, frame = handler.read()
if not status:
break
frames += 1
return frames
cap = cv2.VideoCapture(video_path)
# Slow, inefficient but 100% accurate method
if manual:
frames = manual_count(cap)
# Fast, efficient but inaccurate method
else:
try:
frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
except:
frames = manual_count(cap)
cap.release()
return frames
Điểm chuẩn
if __name__ == '__main__':
import timeit
import cv2
start = timeit.default_timer()
print('frames:', frame_count('fedex.mp4', manual=False))
print(timeit.default_timer() - start, '(s)')
start = timeit.default_timer()
print('frames:', frame_count('fedex.mp4', manual=True))
print(timeit.default_timer() - start, '(s)')
Phương pháp số 1 kết quả
frames: 3671
0.018054921 (s)
Phương pháp số 2 kết quả
frames: 3521
9.447095287 (s)
Lưu ý rằng hai phương pháp khác nhau 150 khung hình và Phương pháp số 2 chậm hơn đáng kể so với Phương pháp số 1 . Do đó, nếu bạn cần tốc độ nhưng sẵn sàng hy sinh độ chính xác, hãy sử dụng Phương pháp số 1. Trong tình huống bạn ổn với độ trễ nhưng cần số khung hình chính xác, hãy sử dụng Phương pháp số 2
Một giải pháp khác mà không phụ thuộc vào các trình nhận lỗi đôi khi CV_CAP_PROP
là xem toàn bộ tệp video của bạn trong một vòng lặp
Việc thu thập thông tin về độ phân giải phức tạp hơn vì một số codec hỗ trợ độ phân giải thay đổi (tương tự như VBR trong các tệp âm thanh trong đó tốc độ bit không phải là hằng số mà thay vào đó bao gồm một số phạm vi được xác định trước).
FPS có thể được tính toán tuy nhiên ở đây bạn gặp phải vấn đề tương tự như với độ phân giải - hằng số (CFR) so với biến (VFR). Đây là một vấn đề liên quan đến luồng đột biến omho. Cá nhân tôi sẽ sử dụng một bộ đếm khung hình, bộ đếm này tăng lên sau mỗi khung hình hợp lệ trong khi ở khoảng thời gian 1 giây, một bộ đếm thời gian (chạy trong luồng nền) sẽ kích hoạt lưu giá trị của bộ đếm hiện tại và sau đó đặt lại nó. Bạn có thể lưu trữ các giá trị trong một danh sách để tính toán tốc độ khung hình trung bình / không đổi ở cuối khi bạn cũng sẽ biết tổng số khung hình mà video có.
Nhược điểm của cách làm khá đơn giản này là bạn phải duyệt qua toàn bộ tệp, điều này - trong trường hợp nó dài vài giờ - chắc chắn sẽ bị người dùng chú ý. Trong trường hợp này, bạn có thể thông minh về nó và làm điều đó trong quy trình nền trong khi cho phép người dùng làm việc khác trong khi ứng dụng của bạn đang thu thập thông tin này về tệp video đã tải.
Ưu điểm là bất kể bạn có tệp video nào miễn là OpenCV có thể đọc từ nó, bạn sẽ nhận được kết quả khá chính xác không giống như kết quả CV_CAP_PROP
có thể có hoặc không hoạt động như bạn mong đợi.