Ubuntu20.04+ROS Noetic下OpenCV Mat.data.fl访问报错求助
问题分析与解决方案
问题根源
升级到Ubuntu 20.04 + ROS Noetic后报错,本质是OpenCV版本变更导致的API差异:
- ROS Melodic依赖OpenCV 3.x,当时
cv::Mat::data是包含类型特定成员的联合(比如fl对应float类型矩阵的指针); - ROS Noetic依赖OpenCV 4.x,
cv::Mat::data被简化为uchar*类型的通用指针,不再有fl这类类型专属成员,直接访问data.fl会触发编译报错。
你之前尝试的at<float>()方法错误,因为at<float>()仅用于获取矩阵中单个元素的值,而非指向整个矩阵数据的指针,后续的指针偏移操作自然无法正常工作。
修复方案
使用OpenCV 4.x推荐的类型安全指针获取方法:cv::Mat::ptr<T>(),它会返回对应类型的矩阵数据指针。
修改代码中获取指针的两行:
float *data_mapx = mapx->ptr<float>(); float *data_mapy = mapy->ptr<float>();
完整修复后的代码
void create_perspecive_undistortion_LUT( Mat *mapx, Mat *mapy, struct ocam_model *ocam_model, float sf) { int i, j; int width = mapx->cols; //New width int height = mapx->rows;//New height float *data_mapx = mapx->ptr<float>(); float *data_mapy = mapy->ptr<float>(); float Nxc = height/2.0; float Nyc = width/2.0; float Nz = -width/sf; double M[3]; double m[2]; for (i=0; i<height; i++) for (j=0; j<width; j++) { M[0] = (i - Nxc); M[1] = (j - Nyc); M[2] = Nz; world2cam(m, M, ocam_model); *( data_mapx + i*width+j ) = (float) m[1]; *( data_mapy + i*width+j ) = (float) m[0]; } }
额外注意事项
- 确保传入的
mapx和mapy矩阵是CV_32FC1类型(单通道float矩阵),否则ptr<float>()会导致未定义行为; - 若需要更安全的边界检查,也可以在循环中直接用
at<float>(i,j)赋值,仅效率略低于指针操作:mapx->at<float>(i,j) = (float)m[1]; mapy->at<float>(i,j) = (float)m[0];
内容的提问来源于stack exchange,提问作者Andi Dwi Prastyo
相关产品推荐
相关产品推荐

