2012-08-12 150 views
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构造函数或元素的访问方法是否有任何错误?

+0

这是C++不是它,而不是C?他们是完全不同的语言。什么是'CvMat'?什么是'_Tchar'?你为什么使用演员? – 2012-08-12 16:35:26

+0

CvMat是矩阵数据结构。 '_tchar'我在创建一个新项目后就这样离开了它。 (它默认显示)。但是你能告诉我主要功能'_tmain'的意思是什么? (这些东西默认显示) – 2012-08-12 18:36:30

+0

你还没有给出你的问题的背景,我们该如何猜测这些东西?请正确标记您的问题。 – 2012-08-12 18:51:58

回答

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; 
} 
+0

谢谢...我已经阅读了一些来自互联网的教程,其中声明,初始化和访问的方式是我在代码中使用的,可以给我一些链接,了解你上述的编程风格...一些链接,详细说明你的操作矩阵方法等。 – 2012-08-13 15:57:42

+0

看看[Opencv cheatsheet](http://opencv.willowgarage.com/wiki/Welcome?action = AttachFile&DO = GET和目标= opencv_cheatsheet.pdf)。很多常用的函数在这个cheatsheet中可以很有效地解释,它也可以在你的opencv源文件夹里找到。 – masad 2012-08-13 20:46:17

+0

为什么你用cout << mat.at (j,i)<<“”;?看来它会逐列初始化矩阵列。 – Guangchun 2013-05-15 17:30:35

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 

请参阅?这有帮助吗?

+0

你似乎对这个问题比这里写的更多。您能否通过首先改善问题来为此做出贡献? – 2012-08-12 16:38:43

+0

正如我之前所说的,他声明“ints”(每个4-8字节并使用mat.data.i)并使用其他类型的指针。 mat.data.ptr(每个无符号字符是1个字节) – 2012-08-12 16:51:35

+0

非常感谢你...我得到的是被宣布为一个int指针我有hav使用data.i,但你能解释为什么递增整数指针加1 4地址? int的大小只有2个字节,所以它应该是地址+2。为什么它的地址是+4? – 2012-08-12 19:06:38

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 

OR

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 
+0

是的,我现在明白了...谢谢你的核心...现在我明白了为什么以前我得到3时,我打印垫的价值。步骤(因为我使用CV_8UC1,矩阵被分配为9个字节,每个元素一个=> 3个字节),现在我使用CV_32SC1,它为每个元素分配4个字节=>一行12个字节... @tuğrulbüyükışık's – 2012-08-13 15:38:50

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; 
}