专栏名称: OpenCV学堂
一个致力于计算机视觉OpenCV原创技术传播的公众号!OpenCV计算机视觉与tensorflow深度学习相关算法原创文章分享、函数使用技巧、源码分析与讨论、,计算机视觉前沿技术介绍,技术专家经验分享,人才交流,学习交流。
目录
相关文章推荐
GiantPandaCV  ·  谈谈DeepSeek原厂推理方案 ·  昨天  
丁香生活研究所  ·  劝你吃蓝莓的理由,不止一个! ·  昨天  
营养师顾中一  ·  明明是乳腺友好食物,却被误会对乳腺有害! ·  4 天前  
51好读  ›  专栏  ›  OpenCV学堂

OpenCV中的Mat对象遍历越界会报错吗?

OpenCV学堂  · 公众号  ·  · 2024-09-11 11:39

正文

点击上方 蓝字 关注我们


微信公众号: OpenCV学堂

关注获取更多计算机视觉与深度学习知识

引言

今天有个课程学员跟我说OpenCV中的Mat遍历访问像素的方法,说他没有检查越界一样可以用,问我是不是OpenCV的Mat有自动的像素越界检查,我印象中是没有的,但是又不敢太肯定,所以就测试了一下。

索引方式遍历测试

使用at方式根据行跟列的索引遍历访问每个像素点,然后我故意从负数开始遍历,我要看看at给我的结果到底是什么?测试代码如下:
std::cout << "height: " << image.rows << " width: " << image.cols << std::endl;for (int row = 0; row < 1000; row++) {  for (int col = -1; col < 1000; col++) {    cv::Vec3b bgr = image.at<:vec3b>(row, col);    if (col < 1) {      std::cout << " col index: " << col << " bgr ( " << bgr << std::endl;    }  }}
输入图像时512x512大小,我故意写成1000x1000,发现是可以执行的,而且不报任何错误跟提示,运行结果如下:

但是我发现当我把代码改成下面这个样子的时候,它会给我报错:

说明通过at获取像素的时候,行号负数,它就崩溃了。 但是超过图像边界大小并不会导致程序崩溃,只是会获取一堆乱七八糟的像素值。

然后把代码改成下面这个样子,不光是遍历访问像素值,还赋值给对应的像素点,这个时候行跟列索引超过512的时候,它就直接崩溃了,图示如下:


指针方式遍历测试

使用行指针方式遍历像素,获取每个像素点像素值,同样我也故意在遍历的时候多遍历一行与一列,要看看指针数据给我输出的到底是什么?测试代码如下:
std::cout << "height: " << image.rows << " width: " << image.cols << std::endl;for (int row = 0; row < image.rows; row++) {  uchar* rowData = image.ptr(row);  for (int col = 0; col < image.cols+1; col++) {    cv::Vec3b bgr = image.at<:vec3b>(row, col);    int b = *rowData++;    int g = *rowData++;    int r = *rowData++;    if (col >= image.cols) {      std::cout <<"out boundary width: "<" >> "<< b << " , " << g << " , " << r << std::endl;    }    image.at<:vec3b>(row, col) = cv::Vec3b(255 - b, 255 - g, 255 - r);  }}
运行结果如下:
可以看出越界访问并不影响并不影响赋值,最后我发现其实row跟col超过索引 一样可以赋值,而且不会出错, 但是当遇到这种值得时候它会随机挂,原因我也没有琢磨清楚,我猜测可能越界访问,然后有内存地址访问得冲突导致,因为看像素值还正常。 欢迎大家参与讨论


结论

千万 不要指望OpenCV中得Mat来给你做任何越界检查 ,这些你都必须自己完成!用OpenCV开发得算法,一旦莫名其妙毫无理由得崩溃,首先查找越界问题。


OpenCV4系统化学习


深度学习系统化学习

推荐阅读

OpenCV4.8+YOLOv8对象检测C++推理演示







请到「今天看啥」查看全文