小白,入門中,不足其指正。剛剛接觸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 |