• OpenCV Mat 只能用静态数组定义时初始化,动态数组赋值给Mat需要逐元素进行. MATLAB,OpenCV,VS混合编程


    opencv,vs2008和matlab混合编程。

     

    一   问题 :  matlab不能找到vs2008编译器:mex –setup 和 mbuild –setup 都不行。

          决 :  matlab2007b换成matlab2009a,总算可以了。

    二  用静态数组 (一维和二维,多维) 初始化Mat矩阵完全正确(注意维数匹配).

        问题  :  动态分配数组 (new ,delete) 初始化mat发生数据问题。

          解决 :  动态数组转存为Mat类型 : Mat声明大小可以通过参数传递,可以使用动态数组的大小变量,进行动态指定;

                                                         定义完成后, 逐元素扫描动态数组,然后将对应下标的元素值赋值给Mat矩阵;

    void dynamicArrToMat( int rows, int cols){
    	
    	/* Dynamic Array declaration and Initialization */
    	float **fData = NULL;
    	fData = new float*[4];
    	for (int i = 0 ; i < 4 ; i++) {
        	fData[i] = new float[8];
    	}
    	for (int i = 0; i < 4; i++) {
    		for (int j = 0; j < 8; j++) {
    			fData[i][j] = 2.0;
    		}
    	}
    
    	/* Mat matrix declaration and Initialization by the element copy from dynamic array */
    	Mat mat_fData(4,8,CV_32FC1);
    	for (int i = 0; i < 4; i++) {
    		for (int j = 0; j < 8; j++) {
    			mat_fData.at<float>(i,j) = fData[i][j];
    		}
    	}
    }
    

     

    下面的这个例子中,静态数组s_data,s_data1,n_data初始化mat_data都没问题.

    动态数组data初始化mat_data后,输出打印Mat数据,数据出现-42000000000000异常

    #include "stdafx.h"
    #include "iostream"
    #include "stdlib.h"
    #include "stdio.h"
    
    #include <cv.h>
    #include <highgui.h>
    
    using namespace std;
    
    float s_data[4][8]={{1006,932,1006,1006,859,1006,932,1006},
    {1333,1333,1247,1333,1247,1247,1247,1247},
    {1840,1840,1840,1778,1778,1778,1716,1778},
    {3374,3328,3465,3419,3419,3419,3374,3419}};
    
    float s_data1[32]={1006,932,1006,1006,859,1006,932,1006,
    1333,1333,1247,1333,1247,1247,1247,1247,
    1840,1840,1840,1778,1778,1778,1716,1778,
    3374,3328,3465,3419,3419,3419,3374,3419};
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    /* dynamic allocate the dynamic array ,and initialed it by NULL */
    float **data=NULL;   
    
    data=new float*[4];   
    for (int i=0;i<4;i++) // Initalized the dynamic array; 
    data[i]=new float[8];
    
    for (int i=0;i<4;i++)
    {
    for (int j=0;j<8;j++)
    data[i][j]=s_data[i][j];
    }
    
    for (int i=0;i<4;i++)
    {
    for (int j=0;j<8;j++)
    cout<<data[i][j]<<" ";
    
    cout<<endl;
    }
    
    float n_data[4][8];
    for (int i=0;i<4;i++)
    {
    for (int j=0;j<8;j++)
    n_data[i][j]=data[i][j];
    }
    
    // CvMat *mat_data=cvCreateMat(5,7,CV_32SC1);
    // cvInitMatHeader(mat_data,5,7,CV_32SC1,data);
    
    /* The above sentence changed as follow .*/
    Mat mat_data = Mat(4,8,CV_32FC1);
    for (int i = 0; i < 4; i++) {
        for (int j = 0 ; j < 8 ; j++) {
             mat_data.at<float>(i,j) = data[i][j];
        }
    }
    
    CvMat mat_data=cvMat(4,8,CV_32FC1,s_data1);
    CvMat mat_data;
     cvInitMatHeader(&mat_data,5,7,CV_32FC1,data);
    
    for (int i=0;i<4;i++)
    {
    for (int j=0;j<8;j++)
    cout<<cvmGet(&mat_data,i,j)<<" ";
    
    cout<<endl;
    }
    
    getchar();
    return 0;
    }
    
     

    跟踪调试 原来mat中*data是一维指针,如果用二维动态数组初始化的话,读取的是地址,而不是其中的数据

     

    Mat Initialed by User Data Pointer

    如下例:

    int cols = 300, rows = 200;
    float* myarr = new float[rows*cols];
    /* 第一步,初始化 CvMat 头*/

    /* 这里更改为逐元素赋值复制,Mat声明时其大小可以通过参数传递,动态指定 */

    CvMat mat = cvMat( rows, cols,
    CV_32FC1,                           // 32 位浮点单通道类型
    myarr                                  // 用户数据指针(数据没有被复制)
    );
    /* 第二步,使用 cv 函数, 例如计算 l2 (Frobenius) 模 */
    double norm = cvNorm( &mat, 0, CV_L2 );
    ...
    delete myarr;

  • 相关阅读:
    获取Unity和UGUUI内置组件的属性名
    Sqlite管理工具
    C#对象属性浅拷贝和深拷贝
    fbx查看软件
    如何区分Unity国内版和国际版
    Unity2019及Unity2020打包android的环境配置
    提高Unity编译dll的速度
    SpringBoot使用swagger
    SpringBoot 使用 Interceptor 拦截器
    SpringBoot 使用 Filter 过滤器
  • 原文地址:https://www.cnblogs.com/xiangwengao/p/2399998.html
Copyright © 2020-2023  润新知