一:学习目标
- How to go through each and every pixel of an image?
- How is OpenCV matrix values stored?
- How to measure the performance of our algorithm?
- What are lookup tables and why use them?
二:图像矩阵在内存中如何存储
2.1 图像容器Mat
Mat和Matlab里的数组格式有点像,但一般是二维向量,如果是灰度图,一般存放
<uchar>
类型;如果是RGB彩色图,存放
<Vec3b>
类型。
单通道灰度图数据存放格式:
多通道的图像中,每列并列存放通道数量的子列,如RGB三通道彩色图:
注意通道的顺序反转了:由RGB转化成了BGR。通常情况内存足够大的话图像的每一行是连续存放的,也就是在内存上图像的所有数据存放成一行,这中情况在访问时可以提供很大方便。可以用 isContinuous()函数来判断图像数组是否为连续的。
三:访问图像中的像素
3.1高效的方法:C操作符[ ]
最快的是直接用C风格的内存访问操作符[]来访问:
CvMat& ScanImageAndReduceC(CvMat& I,const uchar* const table)
{
//accept only char type matrices
CV_ASSERT(I.depth()!=sizeof(uchar));
int channels=I.channels();
int nRows=I.rows;
int nCols=I.cols*channels;
if (I.isContinuous())
{
nCols*=nRows;
nRows=1;
}
int i,j;
for (i=0;i<nRows;++i)
{
p=I.ptr<uchar>(i);
for (j=0;j<nCols;++j)
{
p[j]=table[p[j]];
}
}
return I;
}
这种访问形式就是在每行定义一个指针,然后在内存上直接连续访问。如果整个数组在内存上都是连续存放的,那么只需要定义一个指针就可以访问所有的数据!如单通道的灰度图访问方式如下: