Qt中用OpenCV调用局域网IP摄像头报错:Assertion failed (!_src.empty()) in cvtColor
问题:Qt C++版OpenCV无法读取局域网IP摄像头,Python版正常
尝试在Qt中使用OpenCV读取局域网IP摄像头(地址:http://10.147.17.208:8963),但持续出现错误:
Assertion failed (!_src.empty()) in cvtColor.
Python版OpenCV可以正常读取该摄像头,但Qt中的C++代码无法运行。
无法工作的Qt C++代码
void MainWindow::on_cameraButton_toggled(bool checked) { if(checked){ cap.open("http://10.147.17.208:8963"); timer->start(100); qDebug() << "Timer started"; }else{ timer->stop(); cap.release(); ui->camView->clear(); qDebug() << "Timer stopped"; } } void MainWindow::displayFrame() { qDebug() << "Time out!"; cap.read(frame); if(!cap.isOpened()) qDebug() << "Cap is not opened"; cout << frame; QImage qim = MainWindow::convertMat2QImage(frame); ui->camView->setPixmap(QPixmap::fromImage(qim)); qDebug() << "Displayed one frame!"; }
可正常运行的Python OpenCV代码
import cv2 cap = cv2.VideoCapture('http://10.147.17.208:8963') while True: ret, frame = cap.read() frame = cv2.flip( frame, 1 # 1:水平镜像,-1:垂直镜像 ) cv2.imshow('frame', frame) # 这一步必须有,否则图像无法显示 if cv2.waitKey(1) & 0xFF == ord('q'): break # 当一切完成时,释放捕获 cap.release() cv2.destroyAllWindows()
解决方案
1. 检查帧读取状态
cap.read(frame)会返回布尔值表示是否成功读取帧,原代码未判断该状态就直接处理空帧,是触发断言错误的核心原因。修改displayFrame函数:
void MainWindow::displayFrame() { qDebug() << "Time out!"; bool ret = cap.read(frame); if(!cap.isOpened()) { qDebug() << "Cap is not opened"; return; } if(!ret) { qDebug() << "Failed to read frame"; return; } QImage qim = MainWindow::convertMat2QImage(frame); ui->camView->setPixmap(QPixmap::fromImage(qim)); qDebug() << "Displayed one frame!"; }
2. 确认OpenCV的FFmpeg支持
Qt中使用的OpenCV可能未编译FFmpeg后端(Python版OpenCV通常默认集成),导致无法解析HTTP视频流。可以添加代码检查编译信息:
#include <opencv2/videoio.hpp> // 在cap.open后添加 qDebug() << "OpenCV build info:" << cv::getBuildInformation().c_str();
若输出中无FFmpeg启用项,需重新编译带FFmpeg的OpenCV,或更换预编译的完整版本。
3. 修正Mat转QImage的函数实现
断言错误也可能来自格式不匹配或未处理空帧的转换函数,确保转换前先判断输入有效性,并正确处理色彩空间:
QImage MainWindow::convertMat2QImage(const cv::Mat &mat) { if(mat.empty()) return QImage(); cv::Mat rgbMat; cv::cvtColor(mat, rgbMat, cv::COLOR_BGR2RGB); return QImage(rgbMat.data, rgbMat.cols, rgbMat.rows, rgbMat.step, QImage::Format_RGB888); }
内容的提问来源于stack exchange,提问作者fuso
相关产品推荐
相关产品推荐

