Visual Studio下C++调用OpenCV cvtColor出现未处理异常如何解决
问题排查与解决方法
你遇到的异常是OpenCV操作非法输入时抛出的内部异常,可按以下步骤依次排查:
步骤1:优先排查图片读取失败问题(90%以上此类报错都是该原因)
imread读取失败时会返回空的Mat对象,cvtColor操作空图像会直接抛出异常。你可以在imread后加空判断验证:
Mat img = imread(path); // 新增判断逻辑 if (img.empty()) { cout << "读取图片失败,请检查路径是否正确" << endl; return -1; }
- 路径检查注意事项:
- VS默认工作目录为
.vcxproj项目文件所在目录,你需要确认Resource/lambo.png放在该目录下,而非exe生成的Debug/Release目录 - 可以先替换为绝对路径测试,比如
"C:\\Users\\你的用户名\\Desktop\\lambo.png",注意Windows路径下反斜杠需要转义写两个 - 也可以在
imread时增加IMREAD_COLOR参数强制读取为3通道BGR图像,避免源图像通道数不匹配的问题:
Mat img = imread(path, IMREAD_COLOR); - VS默认工作目录为
步骤2:捕获OpenCV异常获取具体错误信息
如果按步骤1排查后仍报错,可以用try-catch块捕获异常,打印具体错误原因:
try { cvtColor(img, imgHSV, COLOR_BGR2HSV); } catch (const cv::Exception& e) { cout << "OpenCV报错详情:" << e.what() << endl; return -1; }
打印的信息会直接告诉你是输入空、通道数不匹配还是其他参数问题。
其他已知代码bug修复
你的代码里还有两处隐性问题,建议同步修改:
namedWindow参数错误:namedWindow("Trackbars", (640, 200));第二个参数应为窗口标志,括号里的逗号表达式实际传了非法值200,正确写法是:
namedWindow("Trackbars", WINDOW_NORMAL); resizeWindow("Trackbars", 640, 200);
- 循环内
waitKey(0)会导致每次刷新需要手动按键,改为waitKey(1)即可实时响应滑动条参数修改。 - C++标准要求
main函数返回值为int,建议将void main()改为int main(),末尾加返回值。
修复后的完整参考代码
#include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <iostream> using namespace std; using namespace cv; int main() { Mat imgHSV, mask; int hmin = 0, stmin = 0, vmin = 0; int hmax = 179, stmax = 255, vmax = 255; string path = "Resource/lambo.png"; Mat img = imread(path, IMREAD_COLOR); if (img.empty()) { cout << "图片读取失败,请检查路径" << endl; return -1; } cvtColor(img, imgHSV, COLOR_BGR2HSV); namedWindow("Trackbars", WINDOW_NORMAL); resizeWindow("Trackbars", 640, 200); createTrackbar("hmin: ", "Trackbars", &hmin, 179); createTrackbar("hmax: ", "Trackbars", &hmax, 179); createTrackbar("stmin: ", "Trackbars", &stmin, 255); createTrackbar("stmax: ", "Trackbars", &stmax, 255); createTrackbar("vmin: ", "Trackbars", &vmin, 255); createTrackbar("vmax: ", "Trackbars", &vmax, 255); while (true) { Scalar lower(hmin, stmin, vmin); Scalar upper(hmax, stmax, vmax); inRange(imgHSV, lower, upper, mask); imshow("Image", img); imshow("Image HSV", imgHSV); imshow("Image tracked", mask); waitKey(1); } return 0; }
内容的提问来源于stack exchange,提问作者karanforprogram1
相关产品推荐
相关产品推荐

