使用minMaxLoc触发0x00007FFF9320CD29未处理异常的问题排查
问题:OpenCV minMaxLoc函数调用触发未处理异常,无法获取像素位置
我需要获取图像中的最大强度像素,使用OpenCV 4.7.0的minMaxLoc函数时触发了未处理异常:
Unhandled exception at 0x00007FFF9320CD29 in opencv-test.exe: Microsoft C++ exception: cv::Exception at memory location 0x00000050347CF630。
异常出现在minMaxLoc调用后的行,imshow可正常显示视频第一帧;移除&minLoc和&maxLoc参数后异常消失,但我需要获取像素位置。请问问题出在哪里?如何解决?
我的代码如下:
#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main() { string videoURL = "C:/Users/Downloads/kinect-depth-image.mp4"; // set input video VideoCapture cap(videoURL); Mat frame; for (;;) { // get frame from the video cap >> frame; // stop the program if no more images if (frame.rows == 0 || frame.cols == 0) return 0; // show frame imshow("Frame", frame); waitKey(0); double minVal, maxVal; Point minLoc, maxLoc; minMaxLoc(frame, &minVal, &maxVal, &minLoc, &maxLoc); std::cout << "Maximum value within image: " << maxVal << std::endl; // show frame imshow("Frame", frame); //quit on ESC button if (waitKey(1) == 27)break; } return 0; }
问题原因
minMaxLoc函数默认仅支持单通道图像,而你的视频帧大概率是3通道的彩色图像(比如BGR格式)。当传入多通道图像时,传递位置参数(minLoc/maxLoc)会触发异常——因为函数无法确定基于哪个通道计算像素位置;但如果只传值参数(minVal/maxVal),函数会默认把图像当作一维数组处理,因此不会报错,但结果并非单通道的真实最值。
解决方法
你需要先将彩色帧转换为单通道图像,或者指定处理某个特定通道:
方法1:转为灰度图处理
在调用minMaxLoc前添加灰度转换代码,将3通道彩色图转为单通道灰度图:
Mat gray; cvtColor(frame, gray, COLOR_BGR2GRAY); minMaxLoc(gray, &minVal, &maxVal, &minLoc, &maxLoc);
方法2:单独处理某个通道
如果需要针对彩色图像的某一通道(比如蓝色通道)计算最值位置,可以拆分通道后单独处理:
vector<Mat> channels; split(frame, channels); // 处理蓝色通道(channels[0]对应BGR格式的蓝色通道) minMaxLoc(channels[0], &minVal, &maxVal, &minLoc, &maxLoc);
额外注意事项
- 检查视频帧格式:可以用
cout << frame.type() << endl;输出帧类型,比如CV_8UC3表示8位3通道彩色图,CV_16UC1是16位单通道深度图(如果你的Kinect深度视频是这种格式,可直接调用minMaxLoc)。 - 优化循环逻辑:代码中存在两次
waitKey,第一次waitKey(0)会阻塞至按键输入,第二次waitKey(1)仅等待1ms,可能导致交互逻辑混乱,建议统一处理按键事件。
内容的提问来源于stack exchange,提问作者jlsdev
相关产品推荐
相关产品推荐

