初始化矩阵

时间:2012-08-12 14:49:46

标签: c++ opencv matrix element

我写了以下代码:

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 个答案:

答案 0 :(得分: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

请参阅?这有帮助吗?

答案 1 :(得分: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;
}

答案 2 :(得分:0)

您的代码存在一些奇怪的问题。不幸的是,tuğrulbü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

答案 3 :(得分: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(对于signed int)。

此外,当您访问矩阵时,您应该使用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;
}