2014-04-24 103 views
0

我使用OpenCV(C++)Mat作爲我的矩陣,並希望儘可能快地訪問單個Mat元素。從OpenCV的教程中,我找到了有效的存取權限代碼:OpenCV快速mat元素和鄰居訪問

for(i = 0; i < nRows; ++i) 
    { 
     p = I.ptr<uchar>(i); 
     for (j = 0; j < nCols; ++j) 
     { 
      p[j] = table[p[j]]; 
     } 
    } 

對於我的問題,我需要爲計算訪問墊塊元件和其鄰國(I-1,J-1)。我怎樣才能調整給定的代碼來訪問一個單一的mat元素及其周圍的元素?由於速度很重要,我想避免Mat.at<>()。 什麼是訪問Mat值及其鄰居值的最有效方式?

+1

不要太怕mat.at <>(),同時它緩慢邊界在檢查調試模式,它實際上在發佈時相當快。只要停止任何過早的優化。 – berak

回答

1

像素和其相鄰像素可以形成cv::Rect,那麼你可以簡單地使用:

cv::Mat mat = ...; 
cv::Rect roi= ...; // define it properly based on the neighbors defination 
cv::Mat sub_mat = mat(roi); 

如果你的鄰居的定義是不規律的,即它們不能形成一個矩形區域,使用面膜代替。有關示例,請參閱here

+1

這是迭代整個Mat的最有效方法嗎? – user3392074

+1

@ user3392074我不確定這是否是最有效的方式。但它肯定比'cv :: Mat.at()'快。 – herohuyongtao

+0

爲什麼這應該更快? – Micka

0

您可以直接指太::數據:

template<class T, int N> 
T GetPixel(const cv::Mat &img, int x, int y) { 
    int k = (y * img.cols + x) * N; 
    T pixel; 
    for(int i=0;i<N;i++) 
     pixel[i] = *(img.data + k + i); 
    return pixel; 
} 

template<class T,int N> 
void SetPixel(const cv::Mat &img, int x, int y, T t) { 
    int k = (y * img.cols + x) * N; 
    for(int i=0;i<N;i++) 
     *(img.data + k + i) = t[i]; 
} 

template<> 
unsigned char GetPixel<unsigned char, 1>(const cv::Mat &img, int x, int y) { 
    return *(img.data + y * img.cols + x); 
} 

template<> 
void SetPixel<unsigned char, 1>(const cv::Mat &img, int x, int y, unsigned char p) { 
    *(img.data + y * img.cols + x) = p; 
} 




int main() { 
    unsigned char r,g,b; 
    int channels = 3; 
    Mat img = Mat::zeros(256,256, CV_8UC3); 
    for(int x=0;x<img.cols;x+=2) 
     for(int y=0;y<img.rows;y+=2) 
      SetPixel<cv::Vec3b, 3>(img, x, y, cv::Vec3b(255,255,255)); 


    Mat imgGray = Mat::zeros(256,256, CV_8UC1); 
    for(int x=0;x<imgGray.cols;x+=4) 
     for(int y=0;y<imgGray.rows;y+=4) 
      SetPixel<unsigned char, 1>(imgGray, x, y, (unsigned char)255); 



    imwrite("out.jpg", img); 
    imwrite("outGray.jpg", imgGray); 

    return 0; 
} 

這是相當快,我認爲。

out.jpg:

out

outGray.jpg:

outGray