2016年1月26日 星期二

OpenCV Mat取值

參考以下OpenCV這一篇解說
Opencv影像掃描


1. 提到效率當然還是使用純C風格的 [] 取值最快
使用Mat::data來存取,不過我試過似乎只在Mat型態為uchar的時候可以使用
速度理所當然是最快的
可以用以下的形式來掃描影像

uchar* p = img.data;
for(int i = 0; i < img.total(); i++)
    p[i] = 0;

2. iterator是個效率差一點但相對安全許多的方式.
iterator的方式比純C風格慢一些
但多了邊界檢查安全許多

3. at最慢
隨機存取是他的優點,但速度確實是偏慢,
OpenCV的文件也不建議使用at來進行掃描,
at在debug下肯定輸iterator與ptr,而release下有則有可能稍慢或是打平

for(int i = 0; i < img.rows; i++)
{
    for (int j = 0; j < img.cols; j++)
    {
        img.at<uchar>(i,j) = 0;
    }
}

at也可以使用一維的方式存取,
方法就像是純C的那樣,不再贅述

4. ptr比at快
ptr的方式是我現在比較偏好的
因為在掃描影像或是做convolution時常常需要去考慮邊界的問題
而ptr可以讓我選擇在特定的row開始
再加上一個位移選擇到特定的col
比起純C與iterator方式多了彈性
速度也不會慢多少,快上at許多
以下範例是可以略過最外圈的掃描方法

for(int i = 1; i < img.rows-1; i++)
{
    uchar* ptr = img.ptr<uchar>(i);
    for (int j = 1; j < img.cols-1; j++)
    {
        ptr[j] = 0;
    }
}



5.LUT最快
若要將某個特定值換成另一個值,
使用OpenCV提供的core function LUT是最快的,甚至比純C還要快
    Mat lookUpTable(1, 256, CV_8U);
    uchar* p = lookUpTable.data;
    for( int i = 0; i < 256; ++i)
        p[i] = table[i];

先將LUT表給建好
然後輸入A影像,給定一個look up table
輸出的B影像則會依照look up table來替換成你要的值
LUT(A, lookUpTable, B);

2 則留言:

  1. 不好意思
    想請問你一下
    如果我要顯示出一張圖片
    全部的像素質
    用ptr的方式做
    為什麼他是沒有數值跑出來的呢?

    我是只有把ptr[j] = 0;
    改成cout << ptr[j] << endl ;
    這樣

    回覆刪除
  2. 厲害 效能比較幫我很多 謝謝站長分享影像處理經驗

    回覆刪除