3

我写了以下代码:

int _tmain(int argc, _TCHAR* argv[])
{

int vals[]={1,2,3,4,5,6,7,8,9};

CvMat mat = cvMat(3,3,CV_8UC1,vals);

for(int i=0;i<mat.rows;i++)
{
    int* ptr = (int*) (mat.data.ptr + i* mat.step);

    for(int j=0;j<mat.cols;j++)
    {
                printf("%d\t",*ptr++);

    }
    printf("\n");
}

return 0;
}

我得到的输出是:

1              2               3
512            768             1024
196608         262144          327680

矩阵未正确初始化。指针ptr指向每一行的开头并递增它给出相应列中的元素。我的假设正确吗?使用的 cvMat 构造函数或元素的访问方法是否有错误?

4

4 回答 4

1

错误的。mat.data.ptr 用于来自 http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/opencv-intro.html的无符号字符

uchar*  ptr;     // data pointer for an unsigned char matrix

你应该使用

mat.data.i

对于整数

您正确初始化矩阵但由于使用了错误的数据结构指针而将其打印错误。

CvMat                      // 2D array
  |-- int   type;          // elements type (uchar,short,int,float,double) and flags
  |-- int   step;          // full row length in bytes
  |-- int   rows, cols;    // dimensions
  |-- int   height, width; // alternative dimensions reference
  |-- union data;
      |-- uchar*  ptr;     // data pointer for an unsigned char matrix
      |-- short*  s;       // data pointer for a short matrix
      |-- int*    i;       // data pointer for an integer matrix
      |-- float*  fl;      // data pointer for a float matrix
      |-- double* db;      // data pointer for a double matrix

看?这有帮助吗?

于 2012-08-12T14:56:57.450 回答
1

你为什么不使用cv::Mat类?

它有一些方便的功能可以更好地处理内存。

为了在您的情况下声明和初始化cv::Mat,代码将如下所示:

int main()
{
   int vals[] = {1,2,3,4,5,6,7,8,9};

    Mat mat = cv::Mat(3, 3, CV_8UC1, vals).clone();

    for(int i = 0; i < mat.rows; i++)
    {
        for(int j = 0; j < mat.cols; j++)
        {
             cout << mat.at<uchar>(j,i) << " ";
        }
        cout << endl;
    }
    return 0;
}
于 2012-08-12T19:15:44.140 回答
0

除了错误的用法(由 huseyin tugrul buyukisik 解释)你的错误是你在创建矩阵时使用了错误的类型

int vals[] = {1,2,3,4,5,6,7,8,9};
CvMat mat = cvMat(3,3,CV_8UC1,vals); // WRONG TYPE!

创建矩阵时,您应该使用 CV_32SC1(用于有符号整数)。

此外,当您访问矩阵时,您应该使用mat.ptr<int>(row). 完整示例:

int vals[] = {1,2,3,4,5,6,7,8,9};

// Fill matrix content without allocating new memory 
// Beware: changing the content of vals changes the content of mat and vice versa
// Use correct type CV_32SC1 or let OpenCV find the correct one by using
// CV_MAKETYPE(cv::DataDepth<int>::value, 1) instead
cv::Mat mat = cv::Mat(3, 3, CV_32SC1, vals);  

// Print content
for(int row = 0; row < mat.rows; row++)
{
    int* rowPtr = mat.ptr<int>(row);

    for(int col = 0; col < mat.cols; col++)
        std::cout << rowPtr[col] << " ";

    std::cout << std::endl;
}
于 2013-08-13T19:27:39.563 回答
0

您的代码存在一些奇怪的问题。不幸的是,tuğrul büyükışık 的回答只对了一半。看看这些行:

// you reserve 9 integers on the stack (9*4=36bytes)
int vals[]={1,2,3,4,5,6,7,8,9}; 

// declare a matrix of uchars. 3*3*1 byte = 9 bytes
// Now, the matrix thinks it has only 9 bytes allocated.
CvMat mat = cvMat(3,3,CV_8UC1,vals); 

// Now you read the values from the matrix. 
// You actually access all the 36 bytes, but if they weren't wrongly allocated 
// at first, you would have a out-of-bounds access. 
for(int i=0;i<mat.rows;i++)
{
    int* ptr = (int*) (mat.data.ptr + i* mat.step);
}

您必须将所有数据转换为相同的格式:int(4 字节)或 uchar(1 字节)

int vals[]={1,2,3,4,5,6,7,8,9}; 
CvMat mat = cvMat(3,3,CV_32SC1,vals); // 32SC1 means signed integer, 32 bits

或者

unsigned char vals[]={1,2,3,4,5,6,7,8,9};
CvMat mat = cvMat(3,3,CV_8UC1,vals); // 8UC1 means unsigned char, 8 bits
于 2012-08-13T06:36:14.607 回答