2016-01-28 29 views
1

我想在OpenCV中创建一个双通道矩阵,其值是对应的行和列索引对。我可以很容易地做到这一点通过以下方式:双通道cv :: Mat对象充满了行循环索引而没有循环

for (int i = 0 ; i< img_height ; ++ i){ 
    for (int j = 0 ; j < img_width ; ++ j){ 
     src.ptr<Point2f>(i)[j] = Point2f(j,i); 
    } 
} 

我不知道是否有在OpenCV的一种方式,更快速,更简洁的方式来初始化这样一个矩阵,而不必使用这种元素明智的做法。我搜索了文档,但是我没有找到任何可以帮助我达到这个目的的东西。

我问,因为我确实需要我的应用程序更快,所以我正在寻找我可以应用于我的代码的任何可能的改进。

在此先感谢

+1

有没有内置函数来做到这一点。最终你可以[重复播放](http://answers.opencv.org/question/11788/is-there-a-meshgrid-function-in-opencv/)。但是,我认为这个简短的代码段不是瓶颈,即使您可以应用一些改进。你有分析过吗?多久时间?典型的图像宽度和高度? – Miki

+0

图片大小为[320x240],但我将在稍后使用[640x480]。它大约需要0.7ms。当然,这不是我的瓶颈,但每一个最终的小加速都是值得赞赏的。 –

+0

好的。张贴了一个答案。你可以试试你的机器上的代码片段并检查执行时间吗?在我的机器上,这个速度要快一点。 – Miki

回答

2

这里没有内建函数。您最终可以使用repeat来模拟Matlab函数meshgrid,但在这种情况下会变得更慢。

但是,您可以改善几件事情:

  • 得到的指针行的开始了内部循环,因为这将是对各行相同。
  • 避免创建临时对象来存储值。
  • 我想你换了我和j。

看一看这段代码:

Mat2f src(img_height, img_width); 

for (int i = 0; i < img_height; ++i) { 
    Vec2f* ptr = src.ptr<Vec2f>(i); 
    for (int j = 0; j < img_width; ++j) { 
     ptr[j][0] = i; 
     ptr[j][1] = j; 
    } 
} 

这个片段是快一点(毫秒时间):

@MarcoFerro: 1.22755 
@Miki:   0.818491 

测试代码:

#include <opencv2/opencv.hpp> 
using namespace cv; 
using namespace std; 

int main() 
{ 
    int img_height = 480; 
    int img_width = 640; 

    { 
     Mat2f src(img_height, img_width); 

     double tic = double(getTickCount()); 
     for (int i = 0; i< img_height; ++i){ 
      for (int j = 0; j < img_width; ++j){ 
       src.ptr<Point2f>(i)[j] = Point2f(i, j); 
      } 
     } 

     double toc = (double(getTickCount()) - tic) * 1000.0/getTickFrequency(); 
     cout << "@MarcoFerro: \t" << toc << endl; 
    } 
    { 
     Mat2f src(img_height, img_width); 

     double tic = double(getTickCount()); 
     for (int i = 0; i < img_height; ++i) { 
      Vec2f* ptr = src.ptr<Vec2f>(i); 
      for (int j = 0; j < img_width; ++j) { 
       ptr[j][0] = i; 
       ptr[j][1] = j; 
      } 
     } 

     double toc = (double(getTickCount()) - tic) * 1000.0/getTickFrequency(); 
     cout << "@Miki: \t\t" << toc << endl; 
    } 

    getchar(); 
    return 0; 
} 
+0

这里是我的执行时间: MarcoFerro:\t 2.96967 @Miki:\t \t 1.73143 每次它给了我不同的时代,但你的解决方案总是比我快。我将应用您的更改。谢谢:) –

+0

很高兴帮助! – Miki

+0

最后一件事:我和j是正确的,我需要它们作为(x,y)坐标,这就是为什么我交换它们(并且Point2f也接受x和y的参数)。但无论如何,它的工作原理,这是很重要的:)再次感谢 –