直接用cv::Mat::at(y,x)索引中心像素最简单,需先验证mat非空、通道数匹配类型,BGR顺序下Vec3b[0]为蓝,避免误用getRectSubPix或类型不匹配导致崩溃。

用 cv::Mat 直接索引中心像素最简单
OpenCV 的 cv::Mat 是二维数组,行优先存储,中心点坐标就是 (rows/2, cols/2)(整数除法向下取整)。注意:必须确保图像非空且为单通道或三通道(BGR),否则访问会越界或读错通道。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 先检查
mat.empty()和mat.channels(),避免崩溃 - 用
mat.at<:vec3b>(y, x)</:vec3b>读 BGR 图像(y是行号,x是列号) - 灰度图用
mat.at<uchar>(y, x)</uchar>,别误用Vec3b - 中心坐标计算:`int cx = mat.cols / 2; int cy = mat.rows / 2;` —— 不要写反
cols/rows顺序
cv::getRectSubPix 不适合取单像素颜色
这个函数本意是做亚像素级 ROI 提取,需要指定尺寸和浮点中心坐标,返回一个子图。它不能直接返回单个像素值,反而引入插值误差(默认双线性),哪怕你传 Size(1,1),结果也不稳定,还可能因边界处理报错 OpenCV(4.10.0) error: (-215:Assertion failed) !_kernel.empty() in function 'cv::getRectSubPix'。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 别为了“中心”二字硬套
cv::getRectSubPix,它不是取色工具 - 真要亚像素采样,用
cv::remap+ 插值,但那是另一回事 - 单像素读取永远优先用
.at()直接索引
RGB/BGR 顺序搞错会导致颜色看起来“不对”
C++ OpenCV 默认加载图像是 BGR 顺序,cv::Vec3b 的 [0] 是蓝(B),[1] 是绿(G),[2] 是红(R)。如果你按 RGB 打印或显示,就会偏蓝;反过来,如果图像是从 Qt 或 SDL 加载的 RGB 数据,再用 Vec3b 读就会错位。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 打印时明确标注顺序:`printf("B=%d G=%d R=%d", bgr[0], bgr[1], bgr[2]);`
- 不确定来源时,先用
cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB)统一转成 RGB 再处理 - 保存或显示前注意目标 API 要求(比如 OpenGL 纹理通常要 RGB)
多通道图像没指定类型就调用 .at 会崩溃
cv::Mat::at 是模板函数,编译期绑定类型。如果图像实际是 3 通道却用 at<uchar></uchar>,运行时不会报错但读出来的是第一个通道(B 值);如果图像是单通道却用 at<vec3b></vec3b>,程序直接 crash(内存越界)。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 永远根据
mat.channels()和mat.depth()选择对应类型:CV_8UC1 → uchar,CV_8UC3 → Vec3b - 写个封装函数,内部 switch channel 数,避免重复判断
- 调试时加断言:
CV_Assert(mat.channels() == 3 && mat.depth() == CV_8U);
channels() 和 type()。


















