2014-04-24 59 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