杰瑞科技汇

Python OpenCV如何读取AVI视频?

Of course! Working with AVI files in Python using OpenCV is a common task. Here's a comprehensive guide covering reading, writing, and the most important "gotcha" you need to know about AVI and OpenCV.

Python OpenCV如何读取AVI视频?-图1
(图片来源网络,侵删)

Reading an AVI File

Reading a video file is straightforward. You use cv2.VideoCapture() to create a capture object and then loop through the frames.

Code Example: Reading and Displaying an AVI

import cv2
# --- Step 1: Specify the video file path ---
# Replace 'my_video.avi' with the path to your AVI file.
video_path = 'my_video.avi'
# --- Step 2: Create a VideoCapture object ---
# This object will be used to read the video.
cap = cv2.VideoCapture(video_path)
# Check if the video was opened successfully
if not cap.isOpened():
    print(f"Error: Could not open video file at {video_path}")
    exit()
# --- Step 3: Loop through the video frames ---
while True:
    # Read a frame from the video
    # ret is a boolean that is True if a frame was read successfully.
    # frame is the image itself.
    ret, frame = cap.read()
    # If the frame was not read (end of video), break the loop
    if not ret:
        print("End of video or error reading frame.")
        break
    # Display the frame in a window
    cv2.imshow('Video Playback', frame)
    # --- Step 4: Wait for a key press to exit ---
    # The `waitKey(1)` function waits for 1 millisecond for a key press.
    # If the 'q' key is pressed, break the loop.
    if cv2.waitKey(1) & 0xFF == ord('q'):
        print("'q' key pressed. Exiting.")
        break
# --- Step 5: Release resources ---
# Release the VideoCapture object and close all OpenCV windows.
cap.release()
cv2.destroyAllWindows()

Explanation:

  1. cv2.VideoCapture(video_path): This initializes the video capture. It takes the file path as an argument.
  2. cap.isOpened(): A good practice to check if the video file was opened successfully before trying to read from it.
  3. cap.read(): This is the core function. It reads the next frame from the video.
    • It returns two values: a boolean ret (True if successful, False if it's the end of the video or an error occurred) and the frame (the image as a NumPy array).
  4. cv2.imshow(): Displays the frame in a new window.
  5. cv2.waitKey(1): This is crucial. It pauses the script for 1 millisecond. Without it, the while loop would run as fast as possible, and you wouldn't see the video playback. The & 0xFF part is a bitwise AND to ensure the key code is correctly interpreted across different systems.
  6. cap.release() and cv2.destroyAllWindows(): Always do this! It releases the handle on the video file and closes all the windows created by OpenCV, freeing up system resources.

Writing an AVI File (The Important Part)

Writing a video is where you need to be careful. Unlike reading, writing requires you to manually specify the Video Writer (Codec), FPS (Frames Per Second), and Frame Size.

The "Gotcha": Codecs in OpenCV

OpenCV uses the FFmpeg library internally for video I/O. However, it doesn't always support all codecs. The most common and widely supported codec for .avi files is XVID.

  • XVID: This is the most reliable choice for .avi files. It's a high-quality, free codec that OpenCV handles well.
  • MJPG (Motion JPEG): Another option, but it can produce larger files.
  • DIVX: Similar to XVID, but XVID is generally the safer bet.

You specify the codec using a FourCC code. For XVID, this is cv2.VideoWriter_fourcc(*'XVID').

Python OpenCV如何读取AVI视频?-图2
(图片来源网络,侵删)

Code Example: Creating an AVI from a Webcam

This example captures frames from your webcam and saves them as an output.avi file.

import cv2
# --- Step 1: Define output file name and codec ---
output_filename = 'output.avi'
# Use the XVID codec, which is excellent for .avi files
fourcc = cv2.VideoWriter_fourcc(*'XVID')
# --- Step 2: Get properties from the webcam ---
# You need to know the frame size and FPS of your source video/webcam.
# We can get this by creating a temporary VideoCapture object.
temp_cap = cv2.VideoCapture(0) # 0 is the default webcam
if not temp_cap.isOpened():
    print("Error: Could not open webcam.")
    exit()
# Get frame width, height, and FPS
frame_width = int(temp_cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(temp_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = int(temp_cap.get(cv2.CAP_PROP_FPS))
# Release the temporary capture object
temp_cap.release()
print(f"Frame Size: {frame_width}x{frame_height}")
print(f"FPS: {fps}")
# --- Step 3: Create the VideoWriter object ---
# Syntax: cv2.VideoWriter(filename, fourcc, fps, frameSize, isColor=True)
out = cv2.VideoWriter(output_filename, fourcc, fps, (frame_width, frame_height))
# Check if the VideoWriter was created successfully
if not out.isOpened():
    print("Error: Could not open VideoWriter for output.")
    exit()
# --- Step 4: Read frames from webcam and write them to the file ---
print("Recording started. Press 'q' to stop.")
while True:
    ret, frame = cap.read() # Assuming 'cap' is your main webcam capture
    if not ret:
        print("Error reading frame from webcam.")
        break
    # Write the frame to the output file
    out.write(frame)
    # Display the recording frame
    cv2.imshow('Recording', frame)
    # Exit on 'q' key press
    if cv2.waitKey(1) & 0xFF == ord('q'):
        print("'q' key pressed. Stopping recording.")
        break
# --- Step 5: Release resources ---
# Release the VideoWriter and the VideoCapture object
out.release()
cap.release() # Make sure to release your main webcam capture too!
cv2.destroyAllWindows()
print(f"Video successfully saved as {output_filename}")

Explanation of Writing:

  1. *`cv2.VideoWriter_fourcc('XVID')**: This creates the codec object. The*unpacks the string'XVID'` into separate arguments for the function.
  2. cap.get(cv2.CAP_PROP_FRAME_WIDTH): These commands retrieve essential properties from the source video (in this case, the webcam). You must get these properties to create the VideoWriter.
  3. cv2.VideoWriter(...): Initializes the writer.
    • filename: The name of the output file.
    • fourcc: The codec object you created.
    • fps: The frames per second for the output video.
    • frameSize: A tuple (width, height) for the video dimensions.
    • isColor: True for a color video, False for grayscale.
  4. out.write(frame): This is the function that takes a frame (a NumPy array) and appends it to the video file.
  5. out.release(): Crucial for finalizing the video file and saving it to disk.

Common Problems and Solutions

Problem 1: "Can't find camera resource" or "Error opening AVI"

  • Cause: The path to your file is incorrect, or the camera index is wrong.
  • Solution: Double-check the file path. For cameras, try different indices (e.g., 1, 2) or list available cameras.

Problem 2: The output AVI file is 0 KB or corrupted.

  • Cause: This is the most common issue. It usually happens because you forgot to call out.release(). If the script crashes or the VideoWriter is not properly closed, the file headers are not written correctly, and the file is unusable.
  • Solution: Always ensure out.release() is called. Using a try...finally block is a robust way to guarantee this.
# Robust way to ensure release
cap = cv2.VideoCapture(0)
out = cv2.VideoWriter('output.avi', cv2.VideoWriter_fourcc(*'XVID'), 20.0, (640, 480))
try:
    while True:
        ret, frame = cap.read()
        if not ret: break
        out.write(frame)
        if cv2.waitKey(1) & 0xFF == ord('q'): break
finally:
    # This block will always execute, even if there's an error
    print("Releasing resources...")
    cap.release()
    out.release()
    cv2.destroyAllWindows()

Problem 3: The output AVI is huge in size.

  • Cause: The codec (like MJPG) or the high resolution is creating large files.
  • Solution:
    1. Use XVID: It's generally more efficient than MJPG.
    2. Lower the Resolution: Resize the frames before writing them.
    3. Lower the FPS: Reduce the frames per second if your application allows it.
# Example of resizing frames to save space
ret, frame = cap.read()
if not ret: break
# Resize the frame to half its size
small_frame = cv2.resize(frame, (0,0), fx=0.5, fy=0.5)
out.write(small_frame)
分享:
扫描分享到社交APP
上一篇
下一篇