OpenCV 3.xx读取视频文件报错求助:vector下标越界
cap.read(frame) Hey there, let's break down this version-specific video reading issue you're hitting. It's super frustrating when code works perfectly in an older OpenCV release but throws errors in newer ones—especially something as cryptic as a vector subscript out of bounds.
First, let's recap the key details you shared to make sure we're aligned:
- Your AVI video reads fine in OpenCV 2.4.9 (self-compiled)
- Every 3.x version you've tested (including 3.4.0) throws the error when executing
cap.read(frame) - The video uses a "regular encoding" that worked seamlessly in the older version
Likely Root Causes
OpenCV 3.x underwent a major refactor of its video I/O module, which changed how it handles video decoding, metadata parsing, and error checking. The stricter validation in 3.x is probably tripping up on something your 2.4.9 build was able to ignore (like minor metadata inconsistencies or edge-case encoding quirks that the older, more lenient parser overlooked).
Step-by-Step Fixes to Try
1. Inspect Your Video's Exact Encoding & Metadata
First, let's get precise details about your AVI file—sometimes "regular encoding" hides subtle differences that 3.x cares about. Use this command (requires ffmpeg installed) to dump all video info:
ffmpeg -i your_video.avi
Look for lines like Video: mjpeg (MJPG / 0x47504A4D), yuvj420p(pc, bt470bg/unknown/unknown), 640x480, 30 fps, 30 tbr, 30 tbn, 30 tbc—note the codec, resolution, and frame rate. Compare this to what OpenCV 3.x is detecting (see step 4 below).
2. Force a Specific Video Backend
OpenCV 3.x supports multiple backends for video I/O (FFmpeg, VFW, etc.), and sometimes switching to a different one can bypass the bug. Try initializing your VideoCapture with an explicit backend:
// Try FFmpeg first (most robust for video) cv::VideoCapture cap("your_video.avi", cv::CAP_FFMPEG); // If that fails, try the VFW backend (common for older AVI files) // cv::VideoCapture cap("your_video.avi", cv::CAP_VFW);
Make sure your 3.x build has the backend enabled—if you compiled it yourself, double-check that FFmpeg/VFW support was turned on during configuration.
3. Repair the Video File
Older AVI files sometimes have minor metadata glitches that 2.4.9's lenient parser ignores, but 3.x's stricter checks choke on. Use ffmpeg to re-encapsulate (not re-encode) the video to fix these issues:
ffmpeg -i input.avi -c copy output_fixed.avi
This copies the original video/audio streams into a clean AVI container without losing quality. Try reading output_fixed.avi in your 3.x code.
4. Debug OpenCV's Video Properties Before Reading Frames
Add some debug code to check what OpenCV 3.x is seeing before calling cap.read(frame). If it's getting invalid values for frame count or resolution, that could cause the vector subscript error:
cv::VideoCapture cap("your_video.avi"); if (!cap.isOpened()) { std::cerr << "Could not open video!" << std::endl; return -1; } // Print key properties std::cout << "Frame count: " << cap.get(cv::CAP_PROP_FRAME_COUNT) << std::endl; std::cout << "Frame width: " << cap.get(cv::CAP_PROP_FRAME_WIDTH) << std::endl; std::cout << "Frame height: " << cap.get(cv::CAP_PROP_FRAME_HEIGHT) << std::endl; std::cout << "FPS: " << cap.get(cv::CAP_PROP_FPS) << std::endl; // Now try reading frames cv::Mat frame; while (cap.read(frame)) { // Process frame }
If any of these values are 0, negative, or wildly incorrect, that's a sign OpenCV 3.x is misparsing the video's metadata.
5. Check Your OpenCV 3.x Build Configuration
If you're using a pre-built 3.x package, it might be missing support for your video's codec. If you compile OpenCV 3.x yourself, make sure:
- You have the latest FFmpeg development libraries installed
- During CMake configuration,
WITH_FFMPEGis set toON - The output of
cmakeshows that FFmpeg components (likeavcodec,avformat) are successfully detected
Why This Works in 2.4.9 but Not 3.x
OpenCV 2.4.x's video I/O stack was older and more forgiving of non-standard or slightly corrupted video files. The 3.x rewrite aimed to improve performance and maintainability, but in doing so, it tightened up error checking and changed how some codecs are handled—leading to compatibility gaps with older media.
内容的提问来源于stack exchange,提问作者gruffmeister

