OpenCV算法代码崩溃最常见的一个原因!

📄 AI 智能文档扫描仪 -

📄 AI 智能文档扫描仪 -

图片编辑
Python
PyTorch

基于OpenCV透视变换算法,提供文档自动扫描与矫正服务,支持边缘检测、歪斜拉直及去阴影增强,集成WebUI,纯算法零依赖版

学习《OpenCV应用开发:入门、进阶与工程化实践》一书
做真正的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<cv::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<uchar>(row);
	for (int col = 0; col < image.cols+1; col++) {
		cv::Vec3b bgr = image.at<cv::Vec3b>(row, col);
		int b = *rowData++;
		int g = *rowData++;
		int r = *rowData++;
		if (col >= image.cols) {
			std::cout <<"out boundary width: "<<col<<" >> "<< b << " , " << g << " , " << r << std::endl;
		}
		image.at<cv::Vec3b>(row, col) = cv::Vec3b(255 - b, 255 - g, 255 - r);
	}
}

代码运行结果如下:
在这里插入图片描述
可以看出越界访问并不影响并不影响赋值,最后我发现其实row跟col超过索引 一样可以赋值,而且不会出错,但是当遇到这种值得时候它会随机挂,原因我也没有琢磨清楚,我猜测可能越界访问,然后有内存地址访问得冲突导致,因为看像素值还正常。
在这里插入图片描述
在这里插入图片描述

结论

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

学习《OpenCV应用开发:入门、进阶与工程化实践》一书
做真正的OpenCV开发者,从入门到入职,一步到位!

您可能感兴趣的与本文相关的镜像

📄 AI 智能文档扫描仪 -

📄 AI 智能文档扫描仪 -

图片编辑
Python
PyTorch

基于OpenCV透视变换算法,提供文档自动扫描与矫正服务,支持边缘检测、歪斜拉直及去阴影增强,集成WebUI,纯算法零依赖版

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gloomyfish

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值