與OpenCV的第六天

第一件事:訪問圖像中的像素

1. 圖像的數(shù)據(jù)诽俯,是如何以指定的顏色空間和數(shù)據(jù)類型存儲在內(nèi)存中的敲才?

同一個圖像的矩陣的大小取決于所用的顏色空間和數(shù)據(jù)類型晦墙,確切的說取決于通道數(shù)和深度孤钦。

灰度空間矩陣:

灰度矩陣排列

RGB空間矩陣:

RGB矩陣排列

可以發(fā)現(xiàn) OpenCV 在內(nèi)存中子列的通道順序與通常習慣的 RBG 順序相反——BGR歧斟。通常內(nèi)存足夠的情況下,可以實現(xiàn)圖像在內(nèi)存中的連續(xù)存儲偏形,這樣極大地提高了圖像的掃描速度静袖,可以使用 isContinuous() 函數(shù)來判斷矩陣在內(nèi)存中是否為連續(xù)存儲。

2. 顏色空間縮減

若圖像是單通道的并且使用 8 位字符類型俊扭,那么一個像素位置可能有256個不同值队橙,那么如果有三通道呢?那么一個像素位置將會有一千六百多萬種可能顏色萨惑,若果我們隊這些顏色進行逐一分類處理的話那么將對我們算法性能造成極其嚴重的影響捐康。所以我們需要對顏色空間進行一些縮減,比如顏色值 0-9 的按0計算庸蔼,10-19 的按10計算解总,以此類推。
在對整形 "/" 運算中姐仅,會自動去掉余數(shù)那么我們可以這樣操作簡單地實現(xiàn)上面的需求:

int b = 13;
int a = (b/10)*10 = (13/10)*10 = 1*10 = 10;

但是如果每一次都對每個像素進行這樣的計算過程花枫,也是需要很大的時間花銷刻盐,而且這兩種運算(乘、除)又特別費時乌昔。我們可以先將像素的可能性存在表中隙疚,需要用的時候直接從表里面取出來即可壤追。

//先存在表里面
int divideWidth = 10;
uchar table[256];
for (int i = 0,i < 256;i++){
    table[i] = divideWidth * (i/divideWidth);
}

//查找對應值
int key = 111;
int value = table[key];

3. LUT 函數(shù):生成縮減矩陣

在上一點中生成了一個查找表磕道,用來查找某個通道對應的縮減值而非每次都進行計算。接下來我們就需要將目標圖像矩陣進行縮減生成縮減圖像行冰,思路是:

  1. 先生成查找表溺蕉;
  2. 遍歷目標矩陣每一個元素;
  3. 將目標矩陣中每一個元素在查找表中找到對應縮減值悼做;
  4. 將縮減值存入新的矩陣疯特。

很快就寫出了代碼。但是肛走!之前又講到OpenCV是一個開發(fā) 工具 包漓雅,作為工具包這點事情都不能幫我們輕松解決還算什么工具包?所以O(shè)penCV中為我們封裝了一個函數(shù)朽色,并且這個函數(shù)OpenCV官方文檔中是極力推薦我們使用的邻吞,那就是 LUT 函數(shù),函數(shù)原型:

void LUT(InputArray src, InputArray lut, OutputArray dst);
參數(shù) 意義
InputArray src 源矩陣
InputArray lut 查找表
OutputArray dst 輸出矩陣

示例程序:

    //建立查找表
    int div = 100;//值大一點效果比較明顯
    
    //LUT 函數(shù)中需要輸入的是一個InputArray類型
    cv::Mat luTable(1,256, CV_8U);
    uchar* table = luTable.data;
    for (int i = 0; i < 256; i++) {
        table[i] = div * (i/div);
    }
    
    cv::Mat srcImage = cv::imread("/Users/wangxin/Desktop/1.jpg");
    cv::Mat dstImage;
    
    cv::LUT(srcImage, luTable, dstImage);
    cv::imshow("srcImage", srcImage);
    cv::imshow("dstImage", dstImage);
    cv::waitKey();

運行效果圖【原圖】
運行效果圖【縮減圖】

4. 計時函數(shù)

可以利用 getTickCount()getTickFrequency 函數(shù)來進行計時葫男。

  • getTickCount 函數(shù):該函數(shù)返回CPU自某個時間以來所經(jīng)歷的時間周期數(shù)抱冷。
  • getTickFrequency() 函數(shù):該函數(shù)返回CPU一秒鐘走的時鐘周期數(shù)。這樣我們就可以對某個運算進行計時了梢褐。
//起始狀態(tài)的時間周期
double time0 = static_cast<double>(cv::getTickCount());

//圖像處理操作
//~

//結(jié)束時的時間周期數(shù)
double time1 = static_cast<double>(cv::getTickCount());double 
//計算得出花費時間
time = (time1 - time0)/cv::getTickFrequency;
//輸出運行時間
cout<< "此方法運行時間為:" << time << "秒" << endl;

5. 訪問像素的三種方法

  • 指針訪問:C操作符[]旺遮;(最快)
    核心代碼:
int rowNumber = image.rows;
//列數(shù)*通道數(shù)
int colNumber = image.cols*image.channels();
//循環(huán)遍歷像素
for(int i = 0; i < rowNumber; i++){
    uchar* data = image.ptr<uchar>(i);//獲取第i行首地址
    for(int j = 0; j < colNUmber; j++){
          //處理像素
          data[j];
    }
}
  • STL 中的迭代器 iterator(慢)
    核心代碼:
Mat_<Vec3b>::iterator it = outputImage.begen<Vec3b>();//初始位置
Mat_<Vec3b>::iterator itend = outputImage,end<Vec3b>();//結(jié)束位置
for(;it != itend;it++){
    //開始處理每個像素
    (*it)[0];//通道1,藍色通道
    (*it)[1];//通道2盈咳,綠色通道
    (*it)[2];//通道3耿眉,紅色通道
}
  • 動態(tài)地址計算(最慢)
    利用 at 函數(shù)
    核心代碼:
int rowNumber = image.rows;
//列數(shù)*通道數(shù)
int colNumber = image.cols;
//循環(huán)遍歷像素
for(int i = 0; i < rowNumber; i++){
    for(int j = 0; j < colNUmber; j++){
          //處理像素
          image.at<Vec3b>(i,j)[0];//通道1,藍色通道
          image.at<Vec3b>(i,j)[1];//通道2鱼响,綠色通道
          image.at<Vec3b>(i,j)[2];//通道3鸣剪,紅色通道
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市热押,隨后出現(xiàn)的幾起案子西傀,更是在濱河造成了極大的恐慌,老刑警劉巖桶癣,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拥褂,死亡現(xiàn)場離奇詭異,居然都是意外死亡牙寞,警方通過查閱死者的電腦和手機饺鹃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門莫秆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人悔详,你說我怎么就攤上這事镊屎。” “怎么了茄螃?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵缝驳,是天一觀的道長。 經(jīng)常有香客問我归苍,道長用狱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任拼弃,我火速辦了婚禮夏伊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吻氧。我一直安慰自己溺忧,他們只是感情好,可當我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布盯孙。 她就那樣靜靜地躺著鲁森,像睡著了一般。 火紅的嫁衣襯著肌膚如雪镀梭。 梳的紋絲不亂的頭發(fā)上刀森,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天,我揣著相機與錄音报账,去河邊找鬼研底。 笑死,一個胖子當著我的面吹牛透罢,可吹牛的內(nèi)容都是我干的榜晦。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼羽圃,長吁一口氣:“原來是場噩夢啊……” “哼乾胶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起朽寞,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤识窿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后脑融,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體喻频,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年肘迎,在試婚紗的時候發(fā)現(xiàn)自己被綠了甥温。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锻煌。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖姻蚓,靈堂內(nèi)的尸體忽然破棺而出宋梧,到底是詐尸還是另有隱情,我是刑警寧澤狰挡,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布捂龄,位于F島的核電站,受9級特大地震影響圆兵,放射性物質(zhì)發(fā)生泄漏跺讯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一殉农、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧局荚,春花似錦超凳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至首装,卻和暖如春创夜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背仙逻。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工驰吓, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人系奉。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓檬贰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親缺亮。 傳聞我的和親對象是個殘疾皇子翁涤,可洞房花燭夜當晚...
    茶點故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內(nèi)容