小白,入门中,不足其指正。刚刚接触opencv,从一个Matlab风格的编程环境忽然跳转到C++,实在有些不适。单就pixels scanning花了好长时间研究。opencv-tutorials给出了四种方法。这里将比较其中最高效的方法与Mat类里定义的at()的效率。html
本文以opencv-tutorials中给出的color reduction 为例进行比较。编程
为了简化问题,直接对灰度图进行操做,灰度图的获取能够用Mat类里的imread函数(往往看到这个函数都很激动,又有了Matlab的感受)。ide
//read the image data Mat GrayImage; GrayImage = imread("test.jpg",0); //show the image that read namedWindow("OriginalGrayImage"); imshow("OriginalGrayImage",GrayImage);
其中imread的参数0表示的就是读取灰度图。相比于Matlab里面还要用rgb22gray转化,这里就方便一点了哈!函数
原图:this
灰度读取效果:spa
咱们的目的是把读取的图像像素值进行量化,若是将0~255的像素量化成4级,就需将0~63的像素计算成0,64~127的像素计算成为64……3d
由于在C++编译过程当中,uchar/int的结果仍是uchar,因此直接利用下面公式就能够获得指针
注意的是这里我用的是opencv.org上盗的图,图中的10能够用dividewidth替换,dividewidth的值须要根据量化的结果来肯定,好比若是dividewidth=64;那么0~63的像素都会计算成0,64~127的像素都会计算成为64……以此类推,这样就会被量化成4级。code
可是值得注意的是,对于一张100*100的灰度图就须要计算10000次,因此lookup table产生了。lookup table的思路是产生一个0~255的向量,没个存放用上述公式计算的结果,而后遍历的时候只须要查表就能够了,这样对于一个100*100的灰度图,原本须要计算10000次的,如今只须要计算256次。orm
产生lookup table的代码段
uchar table[256]; int div = 64; for(int i=0;i<256;i++) table[i] = (uchar)(div*(i/div));
Mat.ptr<type>(i)能够得到第i行的指针,其中type表示的是Mat中存放的数据类型,通常的灰度图为uchar,rgb图则是Vec3b。Mat.rows和Mat.cols中分别存放的是图像的行数和列数。
具体代码段以下
//get some informations from GrayImage
int nr = GrayImage.rows;
int nc = GrayImage.cols;
uchar* p;
for(int i=0;i<nr;i++)
{
p = GrayImage.ptr<uchar>(i);
for(int j=0;j<nc;j++)
{
p[j] = table[p[j]];
}
}
运行结果:
灰度量化-Mat.at<type>(i,j)
for(int i=0;i<nr;i++) for(int j=0;j<nc;j++) GrayImage.at<uchar>(i,j) = table[GrayImage.at<uchar>(i,j)];
运行结果:
如何得到运行时间
opencv中提供了两个函数,getTickCount()和getTickFrequency();
Well OpenCV offers two simple functions to achieve this getTickCount() and getTickFrequency().
opencv.org盗来的代码段:
double t = (double)getTickCount(); // do something ... t = ((double)getTickCount() - t)/getTickFrequency(); cout << "Times passed in seconds: " << t << endl;
classic C style operator[] |
0.00136458 |
Mat.at<type>(i,j) | 0.00498963 |