最通常的方法就是
img.at(i,j) = 255;
img.at(i,j)[0] = 255;
如果你覺得at操作顯得太笨重了,不想用mat這個類,也可以考慮使用輕量級的mat_類,使用過載操作符()實現取元素的操作。
cv::mat_im2= img; // im2 refers to image
im2(50,100)= 0; // access to row 50 and column 100
對於一幅影象的掃瞄,用at就顯得不太好了,還是是用指標的操作方法更加推薦。先介紹一種上一講提到過的
for (int j=0; j(j);
for (int i=0; i更高效的掃瞄連續影象的做法可能是把w*h的衣服影象看成是乙個1*(w*h)的乙個一維陣列,這個想法是不是有點奇葩,這裡要利用
iscontinuous
這個函式判斷影象內的畫素是否填充滿,使用方法如下:if (img.iscontinuous())
uchar* data = img.ptr(0);
for (int i=0; i更低階的指標操作就是使用mat裡的data指標,之前我稱之為暴力青年,使用方法如下:
uchar* data = img.data;
// img.at(i, j)
data = img.data + i * img.step + j * img.elemsize();
和c++stl裡的迭代器類似,mat的迭代器與之是相容的。是matiterator_。宣告方法如下:
cv::matiterator_it;
cv::mat_::iterator it;
掃瞄影象的方法如下:
mat_::iterator it = img.begin();
mat_::iterator itend = img.end();
for (; it!=itend; it++)
還是用我們之前使用過的gettickcount、gettickfrequency函式測試速度。這裡我就不一一枚舉我測試的結果了,直接上結論。測試發現,好的編寫風格可以提高50%的速度!要想減少程式執行的時間,必要的優化包括如下幾個方面:
(1)記憶體分配是個耗時的工作,優化之;
(2)在迴圈中重複計算已經得到的值,是個費時的工作,優化之;舉例:
int nc = img.cols * img.channels();
for (int i=0; i後者的速度比前者要慢上好多。
(3)使用迭代器也會是速度變慢,但迭代器的使用可以減少程式錯誤的發生機率,考慮這個因素,可以酌情優化
(4)at操作要比指標的操作慢很多,所以對於不連續資料或者單個點處理,可以考慮at操作,對於連續的大量資料,不要使用它
(5)掃瞄連續影象的做法可能是把w*h的衣服影象看成是乙個1*(w*h)的乙個一維陣列這種辦法也可以提高速度。短的迴圈比長迴圈更高效,即使他們的運算元是相同的
以上的這些優化可能對於大家的程式執行速度提高並不明顯,但它們畢竟是個得到速度提公升的好的程式設計策略,希望大家能多採納。
還有就是利用多執行緒也可以高效提高執行速度。openmp和tbb是兩種流行的apt,不過對於多執行緒的東西,我是有些迷糊的,呵呵
對於整行或者整列的資料,可以考慮這種方式處理
img.row(i).setto(scalar(255));
img.col(j).setto(scalar(255));
OpenCV 操作畫素(訪問畫素值)
為構建計算機視覺應用程式,我們需要學會訪問影象的內容,有時也要修改或者建立影象。本章將講講如何操作影象的元素 即畫素 影象本質上就是由陣列組成的矩陣。opencv使用了cv mat結構來操作影象。矩陣中的每乙個元素表示乙個畫素。對灰度影象而言,畫素是8位無符號數 資料型別為unsigned char...
OpenCV訪問畫素值操縱彙總
最通常的方法就是 cpp view plain copy img.at i,j 255 img.at i,j 0 255 如果你覺得at操作顯得太笨重了,不想用mat這個類,也可以考慮使用輕量級的mat 類,使用過載操作符 實現取元素的操作。cpp view plain copy cv mat im...
opencv2 (2)訪問畫素值
從根本上說,一張影象時乙個由數值組成的矩陣,這也是opencv2用cv mat這個資料結構來表示影象的原因。矩陣的每個元素代表乙個畫素,對於灰度影象,畫素有8為無符號數來表示,其中0代表黑色,255代表白色 對於彩色圖象,每個畫素需要三個這樣的8位無符號數來表示三個顏色通道 紅藍綠 此時矩陣的元素是...