You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用cv2读取VideoCapture帧时触发cv2.cvtColor断言失败错误

解决OpenCV cv2.VideoCapture读取摄像头帧时的!_src.empty()错误

错误原因分析

报错(-215:Assertion failed) !_src.empty()直接说明cv2.cvtColor的输入图像img是空的,根源是cap.read()没有成功获取到摄像头帧。你的代码存在两个关键问题:

  • cap.release()和cv2.destroyAllWindows()被放在while(True)循环内部,第一次循环就释放了摄像头资源,后续循环中cap已失效,无法读取帧。
  • 调用cap.read()后未检查返回的ret值,未确认帧是否读取成功就直接处理。

修复步骤

  1. 将释放摄像头、销毁窗口的代码移到循环体外,确保循环结束后再执行资源清理。
  2. 在读取帧后,先判断ret是否为True,若为False则跳出循环,避免处理空帧。
  3. 可选:添加摄像头是否成功打开的检查,提前排查设备连接问题。

修复后的完整代码

import cv2
import numpy as np
import os
from PIL import Image
from Attendance import attendance
from datetime import datetime
from database import*

def getProfile(Id):
    query="SELECT * FROM users WHERE id="+str(Id)
    mycursor.execute(query)
    profile = mycursor.fetchone()
    return profile

detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read("face-trainner.yml")

cap = cv2.VideoCapture(0) # 获取摄像头视频流
# 检查摄像头是否成功打开
if not cap.isOpened():
    print("无法打开摄像头")
    exit()
    
cap.set(3, 640)
cap.set(4, 480)
font = cv2.FONT_HERSHEY_COMPLEX

while(True):
    ret, img = cap.read()
    # 检查帧是否读取成功
    if not ret:
        print("无法获取帧,退出循环")
        break
        
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = detector.detectMultiScale(gray, 1.3, 5)
    
    for (x,y,w,h) in faces:
        cv2.rectangle(img, (x,y), (x+w, y+h), (0,255,0), 2)
        roi_gray = gray[y:y+h, x:x+w]
        roi_color = img[y:y+h, x:x+w]
        
        nbr_predicted, conf = recognizer.predict(gray[y:y+h, x:x+w])
        print(nbr_predicted, conf)
        
        if(conf < 80):  
            profile=getProfile(nbr_predicted)
            if profile != None:
                time_now=datetime.now()
                newdate=time_now.strftime('%Y-%m-%d') 
                newtime=time_now.strftime('%H:%M:%S')
                attendance(nbr_predicted,newtime,newdate)
                cv2.putText(img, "Name: "+str(profile[4]), (x, y+h+30), font, 0.4, (0, 0, 255), 1)
                cv2.putText(img, "Gender: " + str(profile[7]), (x, y + h + 50), font, 0.4, (0, 0, 255), 1)
        else:
            cv2.putText(img, "Name: Unknown", (x, y + h + 30), font, 0.4, (0, 0, 255), 1)
    
    cv2.imshow('Preview',img) # 显示视频画面
    # 按下ESC键退出循环
    if cv2.waitKey(1) & 0xFF == 27:
        break

# 循环结束后释放资源
cap.release()
cv2.destroyAllWindows()

额外说明

  • 修复后的代码新增了摄像头打开检查和帧读取成功判断,能提前排查设备连接问题。
  • 增加了ESC键退出循环的逻辑,避免只能强制终止程序。
  • 删除了原代码中for循环内重复绘制人脸矩形的冗余代码。

内容的提问来源于stack exchange,提问作者Ashish Bula

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 23:37:45