OpenCV學習筆記 存取像素值操做彙總core

在上一講OpenCV學習筆記(四十二)——Mat數據操做之普通青年、文藝青年、暴力青年裏,對Mat內數據的各類讀寫操做進行了速度的比較,都是我本身想到的方法,感受不夠系統,此次整理了下思路,參考了文獻,把能想到的方法進行了彙總,但願能對你們有所幫助。編程

1.存取單個像素值

最一般的方法就是數組

img.at<uchar>(i,j) = 255;

img.at<Vec3b>(i,j)[0] = 255;

若是你以爲at操做顯得太笨重了,不想用Mat這個類,也能夠考慮使用輕量級的Mat_類,使用重載操做符()實現取元素的操做。多線程

cv::Mat_<uchar> im2= img; // im2 refers to image

   im2(50,100)= 0; // access to row 50 and column 100

2.用指針掃描一幅圖像

對於一幅圖像的掃描,用at就顯得不太好了,仍是是用指針的操做方法更加推薦。先介紹一種上一講提到過的函數

for (int j=0; j<nl; j++)

{

        uchar* data= image.ptr<uchar>(j);

        for (int i=0; i<nc; i++)

       {                 

                  data[i] = 255;

        }

}

更高效的掃描連續圖像的作法多是把W*H的衣服圖像當作是一個1*(w*h)的一個一維數組,這個想法是否是有點奇葩,這裏要利用isContinuous這個函數判斷圖像內的像素是否填充滿,使用方法以下:學習

if (img.isContinuous())

{

        nc = img.rows*img.cols*img.channels();

}

uchar* data = img.ptr<uchar>(0);

for (int i=0; i<nc; i++)

{

        data[i] = 255;

}

更低級的指針操做就是使用Mat裏的data指針,以前我稱之爲暴力青年,使用方法以下:測試

uchar* data = img.data;

// img.at(i, j)

data = img.data + i * img.step + j * img.elemSize();

3.用迭代器iterator掃描圖像優化

cv::MatIterator_<Vec3b> it;

或者是:spa

cv::Mat_<Vec3b>::iterator it;

掃描圖像的方法以下:.net

Mat_<Vec3b>::iterator it = img.begin<Vec3b>();

Mat_<Vec3b>::iterator itend = img.end<Vec3b>();

for (; it!=itend; it++)

{

         (*it)[0] = 255;

}

4.高效的scan image方案總結

仍是用咱們以前使用過的getTickCount、getTickFrequency函數測試速度。這裏我就不一一列舉我測試的結果了,直接上結論。測試發現,好的編寫風格能夠提升50%的速度!要想減小程序運行的時間,必要的優化包括以下幾個方面:線程

(1)內存分配是個耗時的工做,優化之

(2)在循環中重複計算已經獲得的值,是個費時的工做,優化之;舉例:

int nc = img.cols * img.channels();

for (int i=0; i<nc; i++)

{.......}

//**************************

for (int i=0; i<img.cols * img.channels(); i++)

{......}

後者的速度比前者要慢上好多。

(3)使用迭代器也會是速度變慢,但迭代器的使用能夠減小程序錯誤的發生概率,考慮這個因素,能夠酌情優化

(4)at操做要比指針的操做慢不少,因此對於不連續數據或者單個點處理,能夠考慮at操做,對於連續的大量數據,不要使用它

(5)掃描連續圖像的作法多是把W*H的衣服圖像當作是一個1*(w*h)的一個一維數組這種辦法也能夠提升速度。短的循環比長循環更高效,即便他們的操做數是相同的

以上的這些優化可能對於你們的程序運行速度提升並不明顯,但它們畢竟是個獲得速度提高的好的編程策略,但願你們能多采納。

還有就是利用多線程也能夠高效提升運行速度。OpenMP和TBB是兩種流行的APT,不過對於多線程的東西,我是有些迷糊的,呵呵

5.整行整列像素值的賦值

對於整行或者整列的數據,能夠考慮這種方式處理

img.row(i).setTo(Scalar(255));

img.col(j).setTo(Scalar(255));

這節就先介紹這麼多攻略吧~但願你們喜歡

相關文章
相關標籤/搜索