使用Yolov5模型对接摄像头时cv2.imdecode返回None报错问题
cv2.imdecode 执行返回None、触发!buf.empty()断言报错解决方案
问题现象
运行摄像头推理示例脚本时,执行image = cv2.imdecode(image, cv2.IMREAD_COLOR)语句返回None,触发OpenCV 4.6.0版本报错:
error: (-215:Assertion failed) !buf.empty() in function 'cv::imdecode_'
前置校验确认:解码前传入的uint8类型numpy数组非空,已按官方教程操作、重装全部依赖后问题仍存在。
相关原代码逻辑如下:
def infer(): # 从摄像头读取当前帧 ret, img = video.read() # 按比例缩放图片提升速度、节省带宽 height, width, channels = img.shape scale = ROBOFLOW_SIZE / max(height, width) img = cv2.resize(img, (round(scale * width), round(scale * height))) # 将图片编码为base64字符串 retval, buffer = cv2.imencode('.jpg', img) img_str = base64.b64encode(buffer) # 向推理接口发请求拿结果 resp = requests.post(upload_url, data=img_str, headers={ "Content-Type": "application/x-www-form-urlencoded" }, stream=True).raw # 解析返回的结果图片 image = np.asarray(bytearray(resp.read()), dtype="uint8") image = cv2.imdecode(image, cv2.IMREAD_COLOR) return image
调试时拿到的中间变量信息:
resp: <urllib3.response.HTTPResponse object at 0x0000015055DE7070> image: array([ 11, 214, 13, ..., 170, 1, 3], dtype=uint8)
问题根因
报错和OpenCV安装、数组是否为空没有关系,核心原因是从接口拿到的字节流不是合法的JPEG格式图片,常见两种触发场景:
- 接口请求参数配置错误(比如请求地址、鉴权信息填错),接口返回的是JSON/纯文本格式的错误提示,不是渲染后的预测结果图,自然无法被图片解码接口识别。
- 开启
stream=True后直接用.raw属性读取响应,没有处理HTTP压缩、流读取截断的问题,拿到的字节流不完整或者被压缩过,不符合图片解码要求。
修复步骤
- 先校验接口返回内容合法性
在发起请求的代码后增加调试逻辑,把接口返回的原始字节存到本地,确认返回内容是不是图片:
raw_content = resp.read() # 将原始返回写入本地文件 with open("debug_resp.bin", "wb") as f: f.write(raw_content)
如果打开这个文件看到的是文本类报错(比如鉴权失败、地址不存在的提示),先核对请求地址、API密钥、模型参数配置,确保接口本身能正常返回图片结果。
2. 替换响应读取逻辑,兼容HTTP响应处理
去掉stream=True配置,直接用响应对象的content属性拿完整返回内容,同时增加请求状态码校验,替换原有请求+解码部分的代码:
resp = requests.post( upload_url, data=img_str, headers={ "Content-Type": "application/x-www-form-urlencoded" } ) # 先校验请求是否成功 if resp.status_code != 200: print(f"接口请求异常,状态码:{resp.status_code},返回信息:{resp.text}") return None # 转换字节数组后解码 image = np.asarray(bytearray(resp.content), dtype="uint8") image = cv2.imdecode(image, cv2.IMREAD_COLOR)
- 本地图片编码环节校验
如果上面两步处理后还是解码失败,增加本地编码校验逻辑,确认传给接口的图片本身没有问题:
retval, buffer = cv2.imencode('.jpg', img) # 把本地编码后的图片存到本地验证 with open("debug_local.jpg", "wb") as f: f.write(buffer)
如果本地存的debug_local.jpg无法正常打开,排查摄像头读取、图片缩放环节的逻辑问题。
内容的提问来源于stack exchange,提问作者Diego Freire
相关产品推荐
相关产品推荐

