C++ 双通道cv::Mat对象填充了行列索引,没有for循环

C++ 双通道cv::Mat对象填充了行列索引,没有for循环,c++,opencv,mat,C++,Opencv,Mat,我想在OpenCV中创建一个双通道矩阵,其值是对应的行和列索引对。我可以通过以下方式轻松做到这一点: for (int i = 0 ; i< img_height ; ++ i){ for (int j = 0 ; j < img_width ; ++ j){ src.ptr<Point2f>(i)[j] = Point2f(j,i); } } for(int i=0;i

我想在OpenCV中创建一个双通道矩阵,其值是对应的行和列索引对。我可以通过以下方式轻松做到这一点:

for (int i = 0 ; i< img_height ; ++ i){
    for (int j = 0 ; j < img_width ; ++ j){
        src.ptr<Point2f>(i)[j] = Point2f(j,i);
    }
}
for(int i=0;i
我想知道OpenCV中是否有一种方法可以更快、更紧凑地初始化这样一个矩阵,而不必使用这种基于元素的方法。我搜索了文档,但没有找到任何可以帮助我实现这一目的的东西

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


提前感谢

此功能没有内置功能。您最终可以使用模拟Matlab函数
meshgrid
,但在这种情况下,速度会慢得多

但是,您可以改进以下几点:

  • 将指向行开头的指针从内部循环中取出,因为每一行的指针都是相同的
  • 避免创建临时对象来存储值
  • 我想你交换了I和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;
    }
}
测试代码:

#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;
}
#包括
使用名称空间cv;
使用名称空间std;
int main()
{
int img_高度=480;
int img_宽度=640;
{
Mat2f src(仪表板高度、仪表板宽度);
double tic=double(getTickCount());
对于(int i=0;i难道没有内置的函数可以做到这一点吗?你最终可以做到。但是,我不认为这个简短的代码片段是一个瓶颈,即使你可以应用一些改进。你分析过它吗?需要多长时间?典型的图像宽度和高度?图像大小是[320x240],但我将使用[640x480]稍后。大约需要0.7毫秒。当然,这不是我的瓶颈,但每一个最终的小速度都是值得赞赏的。好的。发布了一个答案。你能在你的机器上尝试这个片段并检查执行时间吗?在我的机器上,这稍微快一点。这是我的执行时间:MarcoFerro:2.96967@Miki:1.73143每次它给我不同的时间租用时间,但您的解决方案总是比我的快。我将应用您的更改。谢谢:)最后一件事:I和j是正确的,我需要它们作为(x,y)坐标,这就是我交换它们的原因(Point2f也接受参数作为x和y)但不管怎样,它是有效的,这才是重要的:)谢谢,但你说谁的值是对应的一对行和列索引,所以它是y和x。不管怎样,只要按需要放置索引:D
#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;
}