opencv图像都是抽象成cv::Mat类,一个像素矩阵,通过at<像素具体类型>(行,列)来读写像素,他的实现是这么一句
return ((_Tp*)(data + step.p[0] * i0))[i1];
意思是这个矩阵按一行一行的存在data这块内存中,通过i0,和step.p[0]保存的每行像素占的字节个数得到行地址,再通过(_Tp*)这句强制类型转换为_Tp类型的数组,返回第i1个即我们要读写的像素。
所以ocv在内存上分配了一个uchar型内存块,所有算法都是在修改这块内存。
template<typename _Tp> inline
_Tp& Mat::at(int i0, int i1)
{
CV_DbgAssert(dims <= 2);
CV_DbgAssert(data);
CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
CV_DbgAssert((unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()));
CV_DbgAssert(CV_ELEM_SIZE1(traits::Depth<_Tp>::value) == elemSize1());
return ((_Tp*)(data + step.p[0] * i0))[i1];
}