Python中OpenCV读取MATLAB生成的未压缩AVI文件时cap.read()崩溃问题求助
问题分析与解决方案
看起来你遇到的是OpenCV对MATLAB生成的无标准FOURCC标记的rawvideo AVI文件兼容性问题,直接调用cap.read()时因为像素格式解析错误导致内存访问越界,触发段错误(zsh: segmentation fault)。
核心原因
从你提供的ffprobe输出能明确看到:
- 视频编码是
rawvideo,但codec_tag为0x0000(无标准FOURCC标识) - OpenCV的
VideoCapture依赖FOURCC来识别像素格式,当FOURCC缺失时,它无法正确解析bgr24格式的帧数据,进而在读取时引发内存错误 - 你提到灰度AVI能正常读取,是因为MATLAB生成灰度AVI时附带了正确的FOURCC标记,OpenCV可以正常识别
解决方案
方案1:用FFmpeg-python直接读取帧(推荐,无需转码)
既然FFmpeg能正常处理这个视频,我们可以绕开OpenCV的VideoCapture,用ffmpeg-python库直接读取帧数据,再转为OpenCV可用的numpy数组:
import ffmpeg import numpy as np import cv2 video_path = '/Users/aravind/Downloads/test.avi' # 从ffprobe获取的视频参数 width = 192 height = 192 # 启动FFmpeg进程,将视频转为rawvideo格式输出到管道 process = ( ffmpeg .input(video_path) .output('pipe:', format='rawvideo', pix_fmt='bgr24') .run_async(pipe_stdout=True) ) while True: # 读取一帧的字节数据:height*width*3(bgr24每个像素占3字节) frame_bytes = process.stdout.read(width * height * 3) if not frame_bytes: break # 转换为OpenCV兼容的numpy数组 frame = np.frombuffer(frame_bytes, dtype=np.uint8).reshape((height, width, 3)) # 这里可以添加你的帧处理逻辑,比如显示 cv2.imshow('Frame', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break # 清理资源 process.wait() cv2.destroyAllWindows()
方案2:用FFmpeg转码为OpenCV兼容的AVI
先通过FFmpeg给视频添加标准FOURCC标记,再用OpenCV读取:
# 转码为带BGR24 FOURCC的未压缩AVI ffmpeg -i /Users/aravind/Downloads/test.avi -c:v rawvideo -pix_fmt bgr24 -fourcc BGR2 output_compatible.avi
之后用你的原OpenCV代码读取output_compatible.avi即可正常工作。
方案3:修改MATLAB生成AVI的代码
从源头解决,让MATLAB生成带标准FOURCC的AVI文件:
% 创建带明确编码器的VideoWriter对象 vidObj = VideoWriter('test_compatible.avi', 'Uncompressed AVI'); % 确保使用无压缩编码,并指定像素格式对应的FOURCC vidObj.VideoCompressor = 'None'; % 打开文件并写入帧 vidObj.open(); % 示例:写入随机帧 for i = 1:60 frame = uint8(rand(192,192,3)*255); writeVideo(vidObj, frame); end vidObj.close();
这样生成的AVI文件会带有正确的FOURCC标记,OpenCV可以直接读取。
补充说明
cap.isOpened()返回True是因为OpenCV仅验证了AVI文件头的结构合法性,并未检查编码格式的兼容性- 段错误的本质是OpenCV在未知像素格式的情况下,错误计算了帧数据的内存大小,导致访问了不属于程序的内存区域
内容的提问来源于stack exchange,提问作者RajaKrishnappa
相关产品推荐
相关产品推荐

