Python中OpenCV处理网络摄像头视频转灰度后无法播放问题排查
问题:RTSP流转灰度视频保存失败,出现断言错误及OpenH264初始化失败
我想用OpenCV把网络摄像头的RTSP流转换成灰度图并保存为视频文件,但生成的detect.avi无法播放。运行代码时出现cv::icvExtractPattern断言失败错误,添加openh264-1.8.0-win64.dll后又出现libopenh264初始化失败等一系列错误,代码及报错信息如下:
原代码
rtsp_path = f"rtsp://{userid}:{pwd}@{ip_address}:{rtsp_port}/ipcam_h264.sdp" video = cv2.VideoCapture(rtsp_path ) savepath = "detect.avi" frame_Rate = video.get(cv2.CAP_PROP_FPS) height, width, dim = frame.shape rec = cv2.VideoWriter(savepath, cv2.VideoWriter_fourcc(*'DIVX'), frame_Rate, (int(width), int(height))) while (video.isOpened()): ret, frame = video.read() if frame is None: break img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) rec.write(img) if cv2.waitKey(30) & 0xFF == ord('q'): video.release() rec.release() cv2.destroyAllWindows() break cv2.destroyAllWindows() video.release() rec.release()
原始报错信息
OpenCV(4.6.0) D:\a\opencv-python\opencv-python\opencv\modules\videoio\src\cap_images.cpp:267: error: (-215:Assertion failed) number < max_number in function 'cv::icvExtractPattern'
添加openh264-1.8.0-win64.dll后的报错信息
OpenH264 Video Codec provided by Cisco Systems, Inc. [libopenh264 @ 000001b9e01c4700] [OpenH264] this = 0x000001B9DA5EC4D0, Error:MaxSpatialBitrate (288000000) should be larger than SpatialBitrate (536870911), considering it as error setting [libopenh264 @ 000001b9e01c4700] [OpenH264] this = 0x000001B9DA5EC4D0, Error:WelsInitEncoderExt(), ParamValidationExt failed return 16. [libopenh264 @ 000001b9e01c4700] [OpenH264] this = 0x000001B9DA5EC4D0, Error:CWelsH264SVCEncoder::Initialize(), WelsInitEncoderExt failed. [libopenh264 @ 000001b9e01c4700] Initialize failed [ERROR:0@15.734] global /build/opencv/modules/videoio/src/cap_ffmpeg_impl.hpp (2985) open Could not open codec libopenh264, error: Unspecified error (-1313558101) [ERROR:0@15.734] global /build/opencv/modules/videoio/src/cap_ffmpeg_impl.hpp (3002) open VIDEOIO/FFMPEG: Failed to initialize VideoWriter [ERROR:0@24.573] global D:\a\opencv-python\opencv-python\opencv\modules\videoio\src\cap.cpp (597) cv::VideoWriter::open VIDEOIO(CV_IMAGES): raised OpenCV exception: OpenCV(4.6.0) D:\a\opencv-python\opencv-python\opencv\modules\videoio\src\cap_images.cpp:267: error: (-215:Assertion failed) number < max_number in function 'cv::icvExtractPattern'
问题根源分析
- 空指针访问错误:代码在调用
video.read()前就直接访问frame.shape,此时frame未初始化,是None,直接触发断言失败。 - 通道格式不匹配:转换后的灰度图是单通道,但
VideoWriter初始化时默认按3通道配置,写入单帧时格式不兼容。 - 编码库冲突:原代码使用DIVX编码,额外添加OpenH264库会干扰默认编码逻辑,导致码率参数冲突引发初始化失败。
修正后的代码
import cv2 # 替换为你的RTSP参数 userid = "your_user" pwd = "your_pwd" ip_address = "your_ip" rtsp_port = "554" rtsp_path = f"rtsp://{userid}:{pwd}@{ip_address}:{rtsp_port}/ipcam_h264.sdp" video = cv2.VideoCapture(rtsp_path) savepath = "detect.avi" # 先读取一帧确认流有效 ret, frame = video.read() if not ret or frame is None: print("无法读取RTSP流") exit() frame_Rate = video.get(cv2.CAP_PROP_FPS) height, width = frame.shape[:2] # 指定isColor=False,匹配灰度图单通道格式 rec = cv2.VideoWriter(savepath, cv2.VideoWriter_fourcc(*'DIVX'), frame_Rate, (width, height), isColor=False) while video.isOpened(): ret, frame = video.read() if not ret or frame is None: break img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) rec.write(img) if cv2.waitKey(30) & 0xFF == ord('q'): break # 统一释放资源 video.release() rec.release() cv2.destroyAllWindows()
关键修正点
- 先读取有效帧再获取图像尺寸,避免空指针错误。
- 初始化
VideoWriter时添加isColor=False,适配灰度图单通道格式。 - 移除额外添加的OpenH264库,避免编码逻辑冲突。
- 优化资源释放逻辑,统一放在循环外执行。
内容的提问来源于stack exchange,提问作者YuK
相关产品推荐
相关产品推荐

