Ubuntu 18.04下使用USB摄像头检测Aruco fiducial代码运行报错求助
报错原因
Unable to stop the stream: Invalid argument报错本质是VideoCapture和摄像头设备交互异常,核心问题如下:
- 摄像头索引配置错误:当前代码调用的是索引为1的摄像头,绝大多数设备默认第一块摄像头索引为0,索引不匹配会直接导致设备打开失败。
- 冗余代码拖慢帧读取逻辑:Aruco字典、检测器参数的初始化放在了循环内部,每次拉取帧都重复创建对象,容易引发读取超时,触发底层流异常。
- 未指定摄像头后端,OpenCV自动适配时可能和设备驱动不兼容。
修复方案
- 修正摄像头索引:将
cap.open(1)改为cap.open(0),多摄像头设备可依次尝试0、1、2等索引,确认对应摄像头未被其他程序占用、已开启系统权限。 - 指定摄像头后端:打开设备时传入对应系统的后端参数,规避驱动兼容问题,Windows下可使用
CAP_DSHOW,Linux下可使用CAP_V4L2,Mac下可使用CAP_AVFOUNDATION,示例:cap.open(0, cv::CAP_DSHOW)。 - 把Aruco字典、检测器参数的初始化移到循环外,减少不必要的性能开销。
- 可选:增加帧读取失败的日志打印,方便后续定位问题。
修复后完整代码
#include "opencv2/opencv.hpp" #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/aruco.hpp> #include <iostream> using namespace cv; int main(int argc, char** argv) { VideoCapture cap; // 可根据自身系统和摄像头索引修改参数,示例为Windows下调用索引0的摄像头 if(!cap.open(0, cv::CAP_DSHOW)) { std::cout << "摄像头打开失败,请检查索引、权限和设备占用情况" << std::endl; return -1; } // Aruco相关初始化移到循环外,仅创建一次即可 cv::Ptr<cv::aruco::DetectorParameters> parameters = cv::aruco::DetectorParameters::create(); cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_5X5_50); for(;;) { Mat frame; cap >> frame; if( frame.empty() ) { std::cout << "读取帧为空,流中断" << std::endl; break; } std::vector<int> markerIds; std::vector<std::vector<cv::Point2f>> markerCorners, rejectedCandidates; cv::aruco::detectMarkers(frame, dictionary, markerCorners, markerIds, parameters, rejectedCandidates); cv::aruco::drawDetectedMarkers(frame, markerCorners, markerIds); imshow("Camera", frame); if( waitKey(10) == 27 ) break; // 按ESC退出程序 } cap.release(); destroyAllWindows(); return 0; }
内容的提问来源于stack exchange,提问作者skippy57344
相关产品推荐
相关产品推荐

