OpenCV:矩阵迭代

8

我刚接触OpenCV,尝试使用迭代器替代“for”循环,因为对于我的情况,“for”循环速度太慢了。我尝试了一些类似这样的代码:

MatIterator_<uchar> it, end;
for( it = I.begin<uchar>(), end = I.end<uchar>(); it != end; ++it)
{
    //some codes here
}

我的问题是:如何将像这样的for循环转换为其他形式:

for ( int i = 0; i < 500; i ++ )
{
    exampleMat.at<int>(i) = srcMat>.at<int>( i +2, i + 3 )
}

如何将其转换为迭代器模式?也就是说,如何以迭代器形式进行“i +2、i +3”操作?我只能通过“*it”获取相应的值,但无法获得它的计数编号。 非常感谢。
2个回答

23

循环遍历并不慢,慢的是exampleMat.at<int>(i),它会进行范围检查。

为了高效地遍历所有像素,可以使用.ptr()获取每行数据的指针。

for(int row = 0; row < img.rows; ++row) {
    uchar* p = img.ptr(row);
    for(int col = 0; col < img.cols; ++col) {
         *p++  //points to each pixel value in turn assuming a CV_8UC1 greyscale image 
    }

    or 
    for(int col = 0; col < img.cols*3; ++col) {
         *p++  //points to each pixel B,G,R value in turn assuming a CV_8UC3 color image 
    }

}   

亲爱的Martin Beckett和Hammer,非常感谢你们的回答。我根据你们的建议修改了我的代码,然后我有两个问题:第一个是,我使用了“dstMat(cv :: Range :: all(),cv :: Range(i * 5 +1,i * 5 +4))。setTo(* data)”来设置dstMat值,但是在循环外,“dstMat”全部为零。我的第二个问题是:这段代码仍然对每个视频帧使用70-80毫秒,但我最多只有30毫秒。你们有什么想法吗?再次感谢。 - E_learner
我在这里发布了一个新问题: http://stackoverflow.com/questions/11989003/opencv-set-matrix-values-with-ranges - E_learner
有没有办法让ptr方法自动返回与底层数据类型相同的指针?我可以使用auto p = img.ptr<int>(row),但如何替换该语句中的“int”? - winterlight
1
@winterlight - 不是自动的。存储始终为字节(char),头文件定义了您要将其视为什么类型 - 编译器不知道。 - Martin Beckett

1

您需要一种计数变量,并且必须自己声明和更新它。一种紧凑的方法是:

int i = 0;
for( it = I.begin<uchar>(), end = I.end<uchar>(); it != end; ++it,i++)
{
//some codes here involving i+2 and i+3
}

如果您正在寻找超快速访问,我建议您自己操作数据指针。要了解迭代速度的详细解释,请参阅OpenCV 2计算机视觉应用程序编程手册第51页(PDF中为第65页)。您的代码可能看起来像这样。

cv::Mat your_matrix;
//assuming you are using uchar
uchar* data = your_matrix.data();

for(int i = 0; i < some_number; i++)
{
  //operations using *data
  data++;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接