OpenCV中Mat.ptr(i,j)与Mat.ptr<float>(i,j)的差异及报错原因
OpenCV cv::Mat指针赋值的类型匹配问题
问题场景
尝试通过以下代码修改cv::Mat中的值:
void gaussian_high_pass_kernel(cv::Mat& gaussianBlur, float sigma) { float d0 = sigma; for (int i = 0; i < scr.rows; i++) { for (int j = 0; j < scr.cols; j++) { float d = pow(float(i - scr.rows / 2), 2) + pow(float(j - scr.cols / 2), 2); *gaussianBlur.ptr(i, j) = 1 - expf(-d / (2 * d0 * d0)); } } }
但*gaussianBlur.ptr(i, j) = 1 - expf(-d / (2 * d0 * d0))这一行无法正确赋值,导致gaussianBlur中所有值变为-4.31596e+08;修改为*gaussianBlur.ptr<float>(i,j) = 1 - expf(-d / (2 * d0 * d0))后,赋值恢复正常。
解答
两种写法的差异
gaussianBlur.ptr(i, j):这是cv::Mat::ptr()的无模板重载,默认返回uchar*类型指针,对应OpenCV最常用的8位无符号字符(CV_8U)类型的Mat元素。gaussianBlur.ptr<float>(i, j):这是模板化的重载版本,明确指定返回float*类型指针,直接指向Mat中对应位置的float(CV_32F)类型元素。
未指定数据类型时出错的原因
你的gaussianBlur应该是创建为CV_32F(32位浮点型)的Mat,而计算结果1 - expf(...)也是float类型(占4字节内存):
- 当使用无模板的
ptr()时,得到的是uchar*指针,uchar仅占1字节内存。直接把4字节的float值写入1字节的内存空间,会破坏相邻的内存区域,导致Mat中存储的数据完全错乱,读取时就会出现像-4.31596e+08这类无意义的数值。 - 使用
ptr<float>()时,指针类型和赋值的float值类型完全匹配,写入的4字节数据正好对应Mat中CV_32F类型元素的内存空间,因此赋值操作正确执行。
总结:操作cv::Mat的元素时,必须保证指针类型和Mat的实际数据类型一致,否则会引发内存读写错误。
内容的提问来源于stack exchange,提问作者meng lu
相关产品推荐
相关产品推荐

