【问题标题】:Pointer Arithmetic in Opencv Using CvMat?Opencv中使用CvMat的指针算术?
【发布时间】:2013-11-13 21:23:23
【问题描述】:

所以我试图通过指针访问矩阵元素。这是我的代码:

    CvMat *Q = cvCreateMat(3,3, CV_32F);
    for(int i = 0; i < Q->rows ; i++){
    float *ptr = (float *)(Q->data.ptr + i * Q->step );
    for(int j = 0; j < Q->cols ; j++){
        *ptr = 0.0;
        if((i ==0)&&(j==0)) *ptr = 1;
        if((i ==0)&&(j==1)) *ptr = 2;
        if((i ==0)&&(j==2)) *ptr = 3;
        if((i ==1)&&(j==0)) *ptr = 4;
        if((i ==1)&&(j==1)) *ptr = 5;
        if((i ==1)&&(j==2)) *ptr = 6;
        if((i ==2)&&(j==0)) *ptr = 7;
        if((i ==2)&&(j==1)) *ptr = 8;
        if((i ==2)&&(j==2)) *ptr = 9;
        //cout << *ptr << endl;
        //system("pause");
    }
}
cout << CV_MAT_ELEM(*Q,float,0,0) << endl;
cout << CV_MAT_ELEM(*Q,float,0,1) << endl;
cout << CV_MAT_ELEM(*Q,float,0,2) << endl;
cout << CV_MAT_ELEM(*Q,float,1,0) << endl;
cout << CV_MAT_ELEM(*Q,float,1,1) << endl;
cout << CV_MAT_ELEM(*Q,float,1,2) << endl;
cout << CV_MAT_ELEM(*Q,float,2,0) << endl;
cout << CV_MAT_ELEM(*Q,float,2,1) << endl;
cout << CV_MAT_ELEM(*Q,float,2,2) << endl;
system("pause");

我正在尝试将 for 循环中的矩阵设为:

[1 2 3

4 5 6

7 8 9],

但是在计算它们时,我得到:

3

-4.31602e+008

-4.31602e+008

6

-4.31602e+008

-4.31602e+008

9

-4.31602e+008

-4.31602e+008

-4.31602e+008 是从哪里来的?我在这里不明白什么?我对指针有点陌生。

【问题讨论】:

    标签: pointers opencv matrix


    【解决方案1】:

    查看CvMat 的 API(如果您可以使用 c++,也可以考虑使用 Mat)。

    我不完全确定您要在这里完成什么,但是如果您想使用指针访问数据,此时您做的有点不对。

    float *ptr = (float *)(Q->data.ptr + i * Q->step );
    

    这里的步长是一行中的字节数(所以这里是 12,每个元素 4 个字节 * 3 个元素)当你这样做时,指针会根据指针的数据类型自动步进正确的字节数用它算术(好教程here)。为了像数组一样访问它,你应该这样做:

    CvMat *Q = cvCreateMat(3,3, CV_32F);
    for(int i = 0; i < Q->rows ; i++){
      for(int j = 0; j < Q->cols ; j++){
        float *ptr = (float *)(Q->data.ptr) + i*Q->rows + j; //Index is row major
        if((i ==0)&&(j==0)) *ptr = 1;
        if((i ==0)&&(j==1)) *ptr = 2;
        if((i ==0)&&(j==2)) *ptr = 3;
        if((i ==1)&&(j==0)) *ptr = 4;
        if((i ==1)&&(j==1)) *ptr = 5;
        if((i ==1)&&(j==2)) *ptr = 6;
        if((i ==2)&&(j==0)) *ptr = 7;
        if((i ==2)&&(j==1)) *ptr = 8;
        if((i ==2)&&(j==2)) *ptr = 9;
       }
    }
    

    更简单的解决方案是使用现有的 CV_MAT_ELEM 宏。

    CvMat *Q = cvCreateMat(3,3, CV_32F);
    for(int i = 0; i < Q->rows ; i++){
      for(int j = 0; j < Q->cols ; j++){
        CV_MAT_ELEM(*Q, float, i, j) = i*Q->rows + j + 1;
       }
    }
    

    【讨论】:

    • 在你定义ptr的那一行,怎么可能把浮动指针(float)(Q->data.ptr)加到非指针i*上Q->行+j? Q->data.ptr 究竟指向什么?行的第一个元素?
    • CvMat 中的数据存储为一个数组,Q->data.ptr 是指向该数组开头的指针。在该行上,我将 (i*Q->rows+j) 添加到指针的开头,这会将指针沿数组移动很多点。阅读指针算法将帮助您理解:eskimo.com/~scs/cclass/notes/sx10b.html
    【解决方案2】:

    您应该在您的内部 j 循环内增加 ptr

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-29
      • 2010-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多